6#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
19static bool IsJumpAndLinkScratch(
Register reg) {
20 return reg == (FLAG_precompiled_mode ?
TMP :
CODE_REG);
24 : object_pool_(ObjectPool::Handle(
code.GetObjectPool())),
25 target_code_pool_index_(-1) {
33 ASSERT(*
reinterpret_cast<uint16_t*
>(pc - 2) == 0x9082);
35 InstructionPattern::DecodeLoadWordFromPool(pc - 6, ®,
36 &target_code_pool_index_);
37 ASSERT(IsJumpAndLinkScratch(reg));
40ICCallPattern::ICCallPattern(
uword pc,
const Code&
code)
41 : object_pool_(ObjectPool::Handle(
code.GetObjectPool())),
42 target_pool_index_(-1),
43 data_pool_index_(-1) {
52 ASSERT(*
reinterpret_cast<uint16_t*
>(pc - 2) == 0x9082);
55 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
56 pc - 6, ®, &target_pool_index_);
57 ASSERT(IsJumpAndLinkScratch(reg));
59 InstructionPattern::DecodeLoadWordFromPool(data_load_end, ®,
64NativeCallPattern::NativeCallPattern(
uword pc,
const Code&
code)
65 : object_pool_(ObjectPool::Handle(
code.GetObjectPool())),
67 native_function_pool_index_(-1),
68 target_code_pool_index_(-1) {
77 ASSERT(*
reinterpret_cast<uint16_t*
>(pc - 2) == 0x9082);
80 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool(
81 pc - 6, ®, &target_code_pool_index_);
82 ASSERT(IsJumpAndLinkScratch(reg));
83 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, ®,
84 &native_function_pool_index_);
89 return static_cast<CodePtr
>(object_pool_.ObjectAt(target_code_pool_index_));
92void NativeCallPattern::set_target(
const Code&
target)
const {
93 object_pool_.SetObjectAt(target_code_pool_index_,
target);
99 object_pool_.RawValueAt(native_function_pool_index_));
102void NativeCallPattern::set_native_function(
NativeFunction func)
const {
103 object_pool_.SetRawValueAt(native_function_pool_index_,
104 reinterpret_cast<uword>(func));
126 if (instr.opcode() ==
LOAD && instr.funct3() ==
LW) {
128 if (instr.opcode() ==
LOAD && instr.funct3() ==
LD) {
132 *
offset = instr.itype_imm();
137 CInstr cinstr(*
reinterpret_cast<uint16_t*
>(
end - 2));
139 if (cinstr.opcode() ==
C_LW) {
141 if (cinstr.opcode() ==
C_LD) {
144 *
base = cinstr.rs1p();
146 *
offset = cinstr.mem4_imm();
148 *
offset = cinstr.mem8_imm();
162 if (instr.opcode() ==
LUI) {
164 *imm = instr.utype_imm();
169 CInstr cinstr(*
reinterpret_cast<uint16_t*
>(
end - 2));
170 if (cinstr.opcode() ==
C_LUI) {
172 *imm = cinstr.u_imm();
204 CInstr add_instr(*
reinterpret_cast<uint16_t*
>(
end - 2));
205 ASSERT(add_instr.opcode() ==
225 uint16_t parcel = *
reinterpret_cast<uint16_t*
>(pc);
227 CInstr instr(parcel);
229 if (instr.opcode() ==
C_LW) {
230 intptr_t
offset = instr.mem4_imm();
232 if (instr.opcode() ==
C_LD) {
233 intptr_t
offset = instr.mem8_imm();
235 if (instr.rs1p() ==
PP) {
242 }
else if (instr.rs1p() ==
THR) {
243 return Thread::ObjectAtOffset(
offset, obj);
249 if (instr.opcode() ==
LOAD && instr.funct3() ==
LW) {
251 if (instr.opcode() ==
LOAD && instr.funct3() ==
LD) {
253 intptr_t
offset = instr.itype_imm();
254 if (instr.rs1() ==
PP) {
261 }
else if (instr.rs1() ==
THR) {
262 return Thread::ObjectAtOffset(
offset, obj);
265 if ((instr.opcode() ==
OPIMM) && (instr.funct3() ==
ADDI) &&
267 if (instr.itype_imm() == 0) {
268 *obj = Object::null();
272 *obj = Object::bool_true().ptr();
276 *obj = Object::bool_false().ptr();
290void InstructionPattern::EncodeLoadWordFromPoolFixed(
uword end,
295CodePtr CallPattern::TargetCode()
const {
296 return static_cast<CodePtr
>(object_pool_.ObjectAt(target_code_pool_index_));
299void CallPattern::SetTargetCode(
const Code&
target)
const {
300 object_pool_.SetObjectAt(target_code_pool_index_,
target);
305 return object_pool_.ObjectAt(data_pool_index_);
308void ICCallPattern::SetData(
const Object&
data)
const {
310 object_pool_.SetObjectAt(data_pool_index_,
data);
313CodePtr ICCallPattern::TargetCode()
const {
314 return static_cast<CodePtr
>(object_pool_.ObjectAt(target_pool_index_));
317void ICCallPattern::SetTargetCode(
const Code&
target)
const {
318 object_pool_.SetObjectAt(target_pool_index_,
target);
322SwitchableCallPatternBase::SwitchableCallPatternBase(
323 const ObjectPool& object_pool)
324 : object_pool_(object_pool), data_pool_index_(-1), target_pool_index_(-1) {}
327 return object_pool_.ObjectAt(data_pool_index_);
330void SwitchableCallPatternBase::SetData(
const Object&
data)
const {
331 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
332 object_pool_.SetObjectAt(data_pool_index_,
data);
335SwitchableCallPattern::SwitchableCallPattern(
uword pc,
const Code&
code)
336 : SwitchableCallPatternBase(ObjectPool::Handle(
code.GetObjectPool())) {
341uword SwitchableCallPattern::target_entry()
const {
342 return Code::Handle(Code::RawCast(object_pool_.ObjectAt(target_pool_index_)))
343 .MonomorphicEntryPoint();
346void SwitchableCallPattern::SetTarget(
const Code&
target)
const {
347 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
348 object_pool_.SetObjectAt(target_pool_index_,
target);
351BareSwitchableCallPattern::BareSwitchableCallPattern(
uword pc)
352 : SwitchableCallPatternBase(ObjectPool::Handle(
353 IsolateGroup::Current()->object_store()->global_object_pool())) {
359 ASSERT(*
reinterpret_cast<uint16_t*
>(pc - 2) == 0x9082);
362 uword target_load_end = InstructionPattern::DecodeLoadWordFromPool(
363 pc - 2, ®, &data_pool_index_);
366 InstructionPattern::DecodeLoadWordFromPool(target_load_end, ®,
367 &target_pool_index_);
371uword BareSwitchableCallPattern::target_entry()
const {
372 return object_pool_.RawValueAt(target_pool_index_);
375void BareSwitchableCallPattern::SetTarget(
const Code&
target)
const {
376 ASSERT(object_pool_.TypeAt(target_pool_index_) ==
377 ObjectPool::EntryType::kImmediate);
378 object_pool_.SetRawValueAt(target_pool_index_,
379 target.MonomorphicEntryPoint());
382ReturnPattern::ReturnPattern(
uword pc) : pc_(pc) {}
384bool ReturnPattern::IsValid()
const {
385 return *
reinterpret_cast<uint16_t*
>(pc_) == 0x8082;
388bool PcRelativeCallPattern::IsValid()
const {
389 Instr aupic(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_)));
390 if (aupic.opcode() !=
AUIPC)
return false;
391 Instr jalr(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_ + 4)));
392 if (jalr.opcode() !=
JALR)
return false;
393 if (aupic.rd() != jalr.rs1())
return false;
394 if (jalr.rd() !=
RA)
return false;
398bool PcRelativeTailCallPattern::IsValid()
const {
399 Instr aupic(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_)));
400 if (aupic.opcode() !=
AUIPC)
return false;
401 Instr jr(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_ + 4)));
402 if (jr.opcode() !=
JALR)
return false;
403 if (aupic.rd() != jr.rs1())
return false;
404 if (jr.rd() !=
ZR)
return false;
412 EncodeOpcode(
JALR) | EncodeFunct3(
F3_0) | EncodeRd(
ZR) |
416intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
425 if (*
reinterpret_cast<uint16_t*
>(pc_ - 2) == 0x9982) {
429 intptr_t pool_index = -1;
430 InstructionPattern::DecodeLoadWordFromPool(pc_ - 2, ®, &pool_index);
434 ASSERT(FLAG_precompiled_mode);
438 Instr jalr(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_ - 4)));
440 Instr auipc(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_ - 8)));
444 intptr_t pool_index = -1;
445 InstructionPattern::DecodeLoadWordFromPool(pc_ - 8, ®, &pool_index);
#define RA(width, name,...)
#define ASSERT_EQUAL(expected, actual)
CallPattern(uword pc, const Code &code)
bool ObjectAtPoolIndex(const Code &code, intptr_t index, Object *obj)
uint32_t EncodeUTypeImm(intptr_t imm)
bool IsCInstruction(uint16_t parcel)
static constexpr intptr_t kFalseOffsetFromNull
static constexpr intptr_t kTrueOffsetFromNull
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code &code, Object *obj)
static T LoadUnaligned(const T *ptr)
static void StoreUnaligned(T *ptr, T value)
const Register IC_DATA_REG
constexpr intptr_t kWordSize
uint32_t EncodeITypeImm(intptr_t imm)
void(* NativeFunction)(NativeArguments *arguments)
struct PathData * Data(SkPath *path)
void Initialize(zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
std::shared_ptr< const fml::Mapping > data