Flutter Engine
The Flutter Engine
instructions_riscv.h
Go to the documentation of this file.
1// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4// Classes that describe assembly patterns as used by inline caches.
5
6#ifndef RUNTIME_VM_INSTRUCTIONS_RISCV_H_
7#define RUNTIME_VM_INSTRUCTIONS_RISCV_H_
8
9#ifndef RUNTIME_VM_INSTRUCTIONS_H_
10#error Do not include instructions_riscv.h directly; use instructions.h instead.
11#endif
12
13#include "platform/unaligned.h"
14#include "vm/allocation.h"
15#include "vm/constants.h"
16#include "vm/native_function.h"
17#include "vm/tagged_pointer.h"
18
19#if !defined(DART_PRECOMPILED_RUNTIME)
21#endif // !defined(DART_PRECOMPILED_RUNTIME)
22
23namespace dart {
24
25class Code;
26class ICData;
27class Object;
28class ObjectPool;
29
30class InstructionPattern : public AllStatic {
31 public:
32 // Decodes a load sequence ending at 'end' (the last instruction of the
33 // load sequence is the instruction before the one at end). Returns the
34 // address of the first instruction in the sequence. Returns the register
35 // being loaded and the loaded immediate value in the output parameters
36 // 'reg' and 'value' respectively.
38 Register* reg,
39 intptr_t* value);
40
41 // Decodes a load sequence ending at 'end' (the last instruction of the
42 // load sequence is the instruction before the one at end). Returns the
43 // address of the first instruction in the sequence. Returns the register
44 // being loaded and the index in the pool being read from in the output
45 // parameters 'reg' and 'index' respectively.
46 // IMPORTANT: When generating code loading values from pool on ARM64 use
47 // LoadWordFromPool macro instruction instead of emitting direct load.
48 // The macro instruction takes care of pool offsets that can't be
49 // encoded as immediates.
51 Register* reg,
52 intptr_t* index);
53
54 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
55 // instruction load from the pool pointer in PP using the destination
56 // register reg as a temporary for the base address.
57 static void EncodeLoadWordFromPoolFixed(uword end, int32_t offset);
58};
59
60class CallPattern : public ValueObject {
61 public:
63
64 CodePtr TargetCode() const;
65 void SetTargetCode(const Code& target) const;
66
67 private:
68 const ObjectPool& object_pool_;
69
70 intptr_t target_code_pool_index_;
71
72 DISALLOW_COPY_AND_ASSIGN(CallPattern);
73};
74
75class ICCallPattern : public ValueObject {
76 public:
77 ICCallPattern(uword pc, const Code& caller_code);
78
79 ObjectPtr Data() const;
80 void SetData(const Object& data) const;
81
82 CodePtr TargetCode() const;
83 void SetTargetCode(const Code& target) const;
84
85 private:
86 const ObjectPool& object_pool_;
87
88 intptr_t target_pool_index_;
89 intptr_t data_pool_index_;
90
91 DISALLOW_COPY_AND_ASSIGN(ICCallPattern);
92};
93
94class NativeCallPattern : public ValueObject {
95 public:
97
98 CodePtr target() const;
99 void set_target(const Code& target) const;
100
103
104 private:
105 const ObjectPool& object_pool_;
106
107 uword end_;
108 intptr_t native_function_pool_index_;
109 intptr_t target_code_pool_index_;
110
111 DISALLOW_COPY_AND_ASSIGN(NativeCallPattern);
112};
113
114// Instance call that can switch between a direct monomorphic call, an IC call,
115// and a megamorphic call.
116// load guarded cid load ICData load MegamorphicCache
117// load monomorphic target <-> load ICLookup stub -> load MMLookup stub
118// call target.entry call stub.entry call stub.entry
120 public:
121 explicit SwitchableCallPatternBase(const ObjectPool& object_pool);
122
124 void SetData(const Object& data) const;
125
126 protected:
128 intptr_t data_pool_index_;
129 intptr_t target_pool_index_;
130
131 private:
132 DISALLOW_COPY_AND_ASSIGN(SwitchableCallPatternBase);
133};
134
135// See [SwitchableCallBase] for a switchable calls in general.
136//
137// The target slot is always a [Code] object: Either the code of the
138// monomorphic function or a stub code.
140 public:
142
144 void SetTarget(const Code& target) const;
145
146 private:
147 DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
148};
149
150// See [SwitchableCallBase] for a switchable calls in general.
151//
152// The target slot is always a direct entrypoint address: Either the entry point
153// of the monomorphic function or a stub entry point.
155 public:
157
159 void SetTarget(const Code& target) const;
160
161 private:
162 DISALLOW_COPY_AND_ASSIGN(BareSwitchableCallPattern);
163};
164
165class ReturnPattern : public ValueObject {
166 public:
167 explicit ReturnPattern(uword pc);
168
169 // ret = 1 compressed instruction
170 static constexpr intptr_t kLengthInBytes = 2;
171
173
174 bool IsValid() const;
175
176 private:
177 const uword pc_;
178};
179
180class PcRelativePatternBase : public ValueObject {
181 public:
182 static constexpr intptr_t kLengthInBytes = 8;
183 static constexpr intptr_t kLowerCallingRange =
184 static_cast<int32_t>(0x80000000);
185 static constexpr intptr_t kUpperCallingRange =
186 static_cast<int32_t>(0x7FFFFFFE);
187
188 explicit PcRelativePatternBase(uword pc) : pc_(pc) {}
189
190 int32_t distance() {
191 Instr auipc(LoadUnaligned(reinterpret_cast<uint32_t*>(pc_)));
192 Instr jalr(LoadUnaligned(reinterpret_cast<uint32_t*>(pc_ + 4)));
193 return auipc.utype_imm() + jalr.itype_imm();
194 }
195
196 void set_distance(int32_t distance) {
197 Instr auipc(LoadUnaligned(reinterpret_cast<uint32_t*>(pc_)));
198 Instr jalr(LoadUnaligned(reinterpret_cast<uint32_t*>(pc_ + 4)));
199 intx_t imm = distance;
200 intx_t lo = ImmLo(imm);
201 intx_t hi = ImmHi(imm);
202 StoreUnaligned(reinterpret_cast<uint32_t*>(pc_), EncodeUTypeImm(hi) |
203 EncodeRd(auipc.rd()) |
204 EncodeOpcode(AUIPC));
205 StoreUnaligned(reinterpret_cast<uint32_t*>(pc_ + 4),
206 EncodeITypeImm(lo) | EncodeRs1(jalr.rs1()) |
207 EncodeFunct3(F3_0) | EncodeRd(jalr.rd()) |
208 EncodeOpcode(JALR));
209 }
210
211 bool IsValid() const;
212
213 protected:
214 uword pc_;
215};
216
217// auipc ra, hi20
218// jalr ra, lo12(ra)
220 public:
222
223 bool IsValid() const;
224};
225
226// auipc tmp, hi20
227// jalr zero, lo12(tmp)
229 public:
231
232 bool IsValid() const;
233};
234
235// This exists only for the CodeRelocator_OutOfRange tests. Real programs never
236// use trampolines because regular calls have 32-bit of range and trampolines
237// provide no additional range.
239 public:
242
244};
245
246} // namespace dart
247
248#endif // RUNTIME_VM_INSTRUCTIONS_RISCV_H_
void SetTarget(const Code &target) const
CallPattern(uword pc, const Code &code)
CodePtr TargetCode() const
void SetTargetCode(const Code &target) const
void SetData(const Object &data) const
ObjectPtr Data() const
CodePtr TargetCode() const
ICCallPattern(uword pc, const Code &caller_code)
void SetTargetCode(const Code &target) const
intx_t utype_imm() const
Register rd() const
Register rs1() const
intx_t itype_imm() const
static uword DecodeLoadWordFromPool(uword end, Register *reg, intptr_t *index)
static void EncodeLoadWordFromPoolFixed(uword end, int32_t offset)
static uword DecodeLoadWordImmediate(uword end, Register *reg, intptr_t *value)
NativeCallPattern(uword pc, const Code &code)
NativeFunction native_function() const
void set_native_function(NativeFunction target) const
void set_target(const Code &target) const
CodePtr target() const
static constexpr intptr_t kUpperCallingRange
static constexpr int kLengthInBytes
static constexpr intptr_t kLowerCallingRange
void set_distance(int32_t distance)
bool IsValid() const
static constexpr int kLengthInBytes
int pattern_length_in_bytes() const
ReturnPattern(uword pc)
void SetData(const Object &data) const
SwitchableCallPatternBase(const ObjectPool &object_pool)
void SetTarget(const Code &target) const
SwitchableCallPattern(uword pc, const Code &code)
uint8_t value
uint32_t * target
Definition: dart_vm.cc:33
uint32_t EncodeUTypeImm(intptr_t imm)
uintptr_t uword
Definition: globals.h:501
intx_t ImmHi(intx_t imm)
static T LoadUnaligned(const T *ptr)
Definition: unaligned.h:14
static void StoreUnaligned(T *ptr, T value)
Definition: unaligned.h:22
uint32_t EncodeITypeImm(intptr_t imm)
static int8_t data[kExtLength]
void(* NativeFunction)(NativeArguments *arguments)
intx_t ImmLo(intx_t imm)
SeparatedVector2 offset