Flutter Engine
The Flutter Engine
assembler_riscv.h
Go to the documentation of this file.
1// Copyright (c) 2017, 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
5#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_RISCV_H_
6#define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_RISCV_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
13#error Do not include assembler_riscv.h directly; use assembler.h instead.
14#endif
15
16#include <functional>
17
18#include "platform/assert.h"
19#include "platform/utils.h"
20#include "vm/class_id.h"
23#include "vm/constants.h"
24#include "vm/hash_map.h"
25#include "vm/simulator.h"
26
27namespace dart {
28
29// Forward declarations.
30class FlowGraphCompiler;
31class RuntimeEntry;
32class RegisterSet;
33
34namespace compiler {
35
36class Address {
37 public:
38 Address(Register base, intptr_t offset) : base_(base), offset_(offset) {}
39 explicit Address(Register base) : base_(base), offset_(0) {}
40
41 // Prevent implicit conversion of Register to intptr_t.
43
44 Register base() const { return base_; }
45 intptr_t offset() const { return offset_; }
46
47 private:
48 Register base_;
49 intptr_t offset_;
50};
51
52class FieldAddress : public Address {
53 public:
54 FieldAddress(Register base, intptr_t offset)
56
57 // Prevent implicit conversion of Register to intptr_t.
59};
60
61// All functions produce exactly one instruction.
63 public:
65 intptr_t far_branch_level,
66 ExtensionSet extensions);
68
69#if defined(TESTING)
70 void SetExtensions(ExtensionSet extensions) { extensions_ = extensions; }
71#endif
72 bool Supports(Extension extension) const {
73 return extensions_.Includes(extension);
74 }
75 bool Supports(ExtensionSet extensions) const {
76 return extensions_.IncludesAll(extensions);
77 }
78
79 intptr_t far_branch_level() const { return far_branch_level_; }
81 void Bind(Label* label);
82
83 // ==== RV32I ====
84 void lui(Register rd, intptr_t imm);
85 void lui_fixed(Register rd, intptr_t imm);
86 void auipc(Register rd, intptr_t imm);
87
88 void jal(Register rd, Label* label, JumpDistance d = kFarJump);
89 void jal(Label* label, JumpDistance d = kFarJump) { jal(RA, label, d); }
90 void j(Label* label, JumpDistance d = kFarJump) { jal(ZR, label, d); }
91
92 void jalr(Register rd, Register rs1, intptr_t offset = 0);
93 void jalr_fixed(Register rd, Register rs1, intptr_t offset);
94 void jalr(Register rs1, intptr_t offset = 0) { jalr(RA, rs1, offset); }
95 void jr(Register rs1, intptr_t offset = 0) { jalr(ZR, rs1, offset); }
96 void ret() { jalr(ZR, RA, 0); }
97
103 blt(rs2, rs1, l, d);
104 }
106 bge(rs2, rs1, l, d);
107 }
111 bltu(rs2, rs1, l, d);
112 }
114 bgeu(rs2, rs1, l, d);
115 }
116
122
126
127 void addi(Register rd, Register rs1, intptr_t imm);
128 void subi(Register rd, Register rs1, intptr_t imm) { addi(rd, rs1, -imm); }
129 void slti(Register rd, Register rs1, intptr_t imm);
130 void sltiu(Register rd, Register rs1, intptr_t imm);
131 void xori(Register rd, Register rs1, intptr_t imm);
132 void ori(Register rd, Register rs1, intptr_t imm);
133 void andi(Register rd, Register rs1, intptr_t imm);
134 void slli(Register rd, Register rs1, intptr_t shamt);
135 void srli(Register rd, Register rs1, intptr_t shamt);
136 void srai(Register rd, Register rs1, intptr_t shamt);
137
138 void add(Register rd, Register rs1, Register rs2);
139 void sub(Register rd, Register rs1, Register rs2);
140 void sll(Register rd, Register rs1, Register rs2);
141 void slt(Register rd, Register rs1, Register rs2);
142 void sltu(Register rd, Register rs1, Register rs2);
143 void xor_(Register rd, Register rs1, Register rs2);
144 void srl(Register rd, Register rs1, Register rs2);
145 void sra(Register rd, Register rs1, Register rs2);
146 void or_(Register rd, Register rs1, Register rs2);
147 void and_(Register rd, Register rs1, Register rs2);
148
149 void fence(HartEffects predecessor, HartEffects successor);
150 void fence() { fence(kAll, kAll); }
151 void fencei();
152 void ecall();
153 void ebreak(); // Causes SIGTRAP(5).
154
155 void csrrw(Register rd, uint32_t csr, Register rs1);
156 void csrrs(Register rd, uint32_t csr, Register rs1);
157 void csrrc(Register rd, uint32_t csr, Register rs1);
158 void csrr(Register rd, uint32_t csr) { csrrs(rd, csr, ZR); }
159 void csrw(uint32_t csr, Register rs) { csrrw(ZR, csr, rs); }
160 void csrs(uint32_t csr, Register rs) { csrrs(ZR, csr, rs); }
161 void csrc(uint32_t csr, Register rs) { csrrc(ZR, csr, rs); }
162 void csrrwi(Register rd, uint32_t csr, uint32_t imm);
163 void csrrsi(Register rd, uint32_t csr, uint32_t imm);
164 void csrrci(Register rd, uint32_t csr, uint32_t imm);
165 void csrwi(uint32_t csr, uint32_t imm) { csrrwi(ZR, csr, imm); }
166 void csrsi(uint32_t csr, uint32_t imm) { csrrsi(ZR, csr, imm); }
167 void csrci(uint32_t csr, uint32_t imm) { csrrci(ZR, csr, imm); }
168
169 void trap(); // Permanently reserved illegal instruction; causes SIGILL(4).
170
171 void nop() { addi(ZR, ZR, 0); }
172 void li(Register rd, intptr_t imm) { addi(rd, ZR, imm); }
173 void mv(Register rd, Register rs) { addi(rd, rs, 0); }
174 void not_(Register rd, Register rs) { xori(rd, rs, -1); }
175 void neg(Register rd, Register rs) { sub(rd, ZR, rs); }
176
177 void snez(Register rd, Register rs) { sltu(rd, ZR, rs); }
178 void seqz(Register rd, Register rs) { sltiu(rd, rs, 1); }
179 void sltz(Register rd, Register rs) { slt(rd, rs, ZR); }
180 void sgtz(Register rd, Register rs) { slt(rd, ZR, rs); }
181
183 beq(rs, ZR, label, distance);
184 }
186 bne(rs, ZR, label, distance);
187 }
189 bge(ZR, rs, label, distance);
190 }
192 bge(rs, ZR, label, distance);
193 }
195 blt(rs, ZR, label, distance);
196 }
198 blt(ZR, rs, label, distance);
199 }
200
201 // ==== RV64I ====
202#if XLEN >= 64
203 void lwu(Register rd, Address addr);
204 void ld(Register rd, Address addr);
205
206 void sd(Register rs2, Address addr);
207
208 void addiw(Register rd, Register rs1, intptr_t imm);
209 void subiw(Register rd, Register rs1, intptr_t imm) { addiw(rd, rs1, -imm); }
210 void slliw(Register rd, Register rs1, intptr_t shamt);
211 void srliw(Register rd, Register rs1, intptr_t shamt);
212 void sraiw(Register rd, Register rs1, intptr_t shamt);
213
214 void addw(Register rd, Register rs1, Register rs2);
215 void subw(Register rd, Register rs1, Register rs2);
216 void sllw(Register rd, Register rs1, Register rs2);
217 void srlw(Register rd, Register rs1, Register rs2);
218 void sraw(Register rd, Register rs1, Register rs2);
219
220 void negw(Register rd, Register rs) { subw(rd, ZR, rs); }
221 void sextw(Register rd, Register rs) { addiw(rd, rs, 0); }
222#endif // XLEN >= 64
223
224#if XLEN == 32
225 void lx(Register rd, Address addr) { lw(rd, addr); }
226 void sx(Register rs2, Address addr) { sw(rs2, addr); }
227#elif XLEN == 64
228 void lx(Register rd, Address addr) { ld(rd, addr); }
229 void sx(Register rs2, Address addr) { sd(rs2, addr); }
230#elif XLEN == 128
231 void lx(Register rd, Address addr) { lq(rd, addr); }
232 void sx(Register rs2, Address addr) { sq(rs2, addr); }
233#endif
234
235 // ==== RV32M ====
236 void mul(Register rd, Register rs1, Register rs2);
237 void mulh(Register rd, Register rs1, Register rs2);
238 void mulhsu(Register rd, Register rs1, Register rs2);
239 void mulhu(Register rd, Register rs1, Register rs2);
240 void div(Register rd, Register rs1, Register rs2);
241 void divu(Register rd, Register rs1, Register rs2);
242 void rem(Register rd, Register rs1, Register rs2);
243 void remu(Register rd, Register rs1, Register rs2);
244
245 // ==== RV64M ====
246#if XLEN >= 64
247 void mulw(Register rd, Register rs1, Register rs2);
248 void divw(Register rd, Register rs1, Register rs2);
249 void divuw(Register rd, Register rs1, Register rs2);
250 void remw(Register rd, Register rs1, Register rs2);
251 void remuw(Register rd, Register rs1, Register rs2);
252#endif // XLEN >= 64
253
254 // ==== RV32A ====
255 void lrw(Register rd,
257 std::memory_order order = std::memory_order_relaxed);
258 void scw(Register rd,
259 Register rs2,
261 std::memory_order order = std::memory_order_relaxed);
263 Register rs2,
265 std::memory_order order = std::memory_order_relaxed);
267 Register rs2,
269 std::memory_order order = std::memory_order_relaxed);
271 Register rs2,
273 std::memory_order order = std::memory_order_relaxed);
275 Register rs2,
277 std::memory_order order = std::memory_order_relaxed);
279 Register rs2,
281 std::memory_order order = std::memory_order_relaxed);
283 Register rs2,
285 std::memory_order order = std::memory_order_relaxed);
287 Register rs2,
289 std::memory_order order = std::memory_order_relaxed);
291 Register rs2,
293 std::memory_order order = std::memory_order_relaxed);
295 Register rs2,
297 std::memory_order order = std::memory_order_relaxed);
298
299 // ==== RV64A ====
300#if XLEN >= 64
301 void lrd(Register rd,
303 std::memory_order order = std::memory_order_relaxed);
304 void scd(Register rd,
305 Register rs2,
307 std::memory_order order = std::memory_order_relaxed);
308 void amoswapd(Register rd,
309 Register rs2,
311 std::memory_order order = std::memory_order_relaxed);
312 void amoaddd(Register rd,
313 Register rs2,
315 std::memory_order order = std::memory_order_relaxed);
316 void amoxord(Register rd,
317 Register rs2,
319 std::memory_order order = std::memory_order_relaxed);
320 void amoandd(Register rd,
321 Register rs2,
323 std::memory_order order = std::memory_order_relaxed);
324 void amoord(Register rd,
325 Register rs2,
327 std::memory_order order = std::memory_order_relaxed);
328 void amomind(Register rd,
329 Register rs2,
331 std::memory_order order = std::memory_order_relaxed);
332 void amomaxd(Register rd,
333 Register rs2,
335 std::memory_order order = std::memory_order_relaxed);
336 void amominud(Register rd,
337 Register rs2,
339 std::memory_order order = std::memory_order_relaxed);
340 void amomaxud(Register rd,
341 Register rs2,
343 std::memory_order order = std::memory_order_relaxed);
344#endif // XLEN >= 64
345
346#if XLEN == 32
347 void lr(Register rd,
349 std::memory_order order = std::memory_order_relaxed) {
350 lrw(rd, addr, order);
351 }
352 void sc(Register rd,
353 Register rs2,
355 std::memory_order order = std::memory_order_relaxed) {
356 scw(rd, rs2, addr, order);
357 }
358#elif XLEN == 64
359 void lr(Register rd,
360 Address addr,
361 std::memory_order order = std::memory_order_relaxed) {
362 lrd(rd, addr, order);
363 }
364 void sc(Register rd,
365 Register rs2,
366 Address addr,
367 std::memory_order order = std::memory_order_relaxed) {
368 scd(rd, rs2, addr, order);
369 }
370#elif XLEN == 128
371 void lr(Register rd,
372 Address addr,
373 std::memory_order order = std::memory_order_relaxed) {
374 lrq(rd, addr, order);
375 }
376 void sc(Register rd,
377 Register rs2,
378 Address addr,
379 std::memory_order order = std::memory_order_relaxed) {
380 scq(rd, rs2, addr, order);
381 }
382#endif
383
384 // ==== RV32F ====
387 // rd := (rs1 * rs2) + rs3
389 FRegister rs1,
390 FRegister rs2,
391 FRegister rs3,
392 RoundingMode rounding = RNE);
393 // rd := (rs1 * rs2) - rs3
395 FRegister rs1,
396 FRegister rs2,
397 FRegister rs3,
398 RoundingMode rounding = RNE);
399 // rd := -(rs1 * rs2) + rs3
401 FRegister rs1,
402 FRegister rs2,
403 FRegister rs3,
404 RoundingMode rounding = RNE);
405 // rd := -(rs1 * rs2) - rs3
407 FRegister rs1,
408 FRegister rs2,
409 FRegister rs3,
410 RoundingMode rounding = RNE);
412 FRegister rs1,
413 FRegister rs2,
414 RoundingMode rounding = RNE);
416 FRegister rs1,
417 FRegister rs2,
418 RoundingMode rounding = RNE);
420 FRegister rs1,
421 FRegister rs2,
422 RoundingMode rounding = RNE);
424 FRegister rs1,
425 FRegister rs2,
426 RoundingMode rounding = RNE);
427 void fsqrts(FRegister rd, FRegister rs1, RoundingMode rounding = RNE);
431 void fmins(FRegister rd, FRegister rs1, FRegister rs2);
432 void fmaxs(FRegister rd, FRegister rs1, FRegister rs2);
433 void feqs(Register rd, FRegister rs1, FRegister rs2);
434 void flts(Register rd, FRegister rs1, FRegister rs2);
435 void fles(Register rd, FRegister rs1, FRegister rs2);
436 void fgts(Register rd, FRegister rs1, FRegister rs2) { flts(rd, rs2, rs1); }
437 void fges(Register rd, FRegister rs1, FRegister rs2) { fles(rd, rs2, rs1); }
439 // int32_t <- float
440 void fcvtws(Register rd, FRegister rs1, RoundingMode rounding = RNE);
441 // uint32_t <- float
442 void fcvtwus(Register rd, FRegister rs1, RoundingMode rounding = RNE);
443 // float <- int32_t
444 void fcvtsw(FRegister rd, Register rs1, RoundingMode rounding = RNE);
445 // float <- uint32_t
446 void fcvtswu(FRegister rd, Register rs1, RoundingMode rounding = RNE);
447
448 void fmvs(FRegister rd, FRegister rs) { fsgnjs(rd, rs, rs); }
449 void fabss(FRegister rd, FRegister rs) { fsgnjxs(rd, rs, rs); }
450 void fnegs(FRegister rd, FRegister rs) { fsgnjns(rd, rs, rs); }
451
452 // xlen <--bit_cast-- float
453 void fmvxw(Register rd, FRegister rs1);
454 // float <--bit_cast-- xlen
455 void fmvwx(FRegister rd, Register rs1);
456
457 // ==== RV64F ====
458#if XLEN >= 64
459 // int64_t <- double
460 void fcvtls(Register rd, FRegister rs1, RoundingMode rounding = RNE);
461 // uint64_t <- double
462 void fcvtlus(Register rd, FRegister rs1, RoundingMode rounding = RNE);
463 // double <- int64_t
464 void fcvtsl(FRegister rd, Register rs1, RoundingMode rounding = RNE);
465 // double <- uint64_t
466 void fcvtslu(FRegister rd, Register rs1, RoundingMode rounding = RNE);
467#endif // XLEN >= 64
468
469 // ==== RV32D ====
472 // rd := (rs1 * rs2) + rs3
474 FRegister rs1,
475 FRegister rs2,
476 FRegister rs3,
477 RoundingMode rounding = RNE);
478 // rd := (rs1 * rs2) - rs3
480 FRegister rs1,
481 FRegister rs2,
482 FRegister rs3,
483 RoundingMode rounding = RNE);
484 // rd := -(rs1 * rs2) - rs3
486 FRegister rs1,
487 FRegister rs2,
488 FRegister rs3,
489 RoundingMode rounding = RNE);
490 // rd := -(rs1 * rs2) + rs3
492 FRegister rs1,
493 FRegister rs2,
494 FRegister rs3,
495 RoundingMode rounding = RNE);
497 FRegister rs1,
498 FRegister rs2,
499 RoundingMode rounding = RNE);
501 FRegister rs1,
502 FRegister rs2,
503 RoundingMode rounding = RNE);
505 FRegister rs1,
506 FRegister rs2,
507 RoundingMode rounding = RNE);
509 FRegister rs1,
510 FRegister rs2,
511 RoundingMode rounding = RNE);
512 void fsqrtd(FRegister rd, FRegister rs1, RoundingMode rounding = RNE);
516 void fmind(FRegister rd, FRegister rs1, FRegister rs2);
517 void fmaxd(FRegister rd, FRegister rs1, FRegister rs2);
518 void fcvtsd(FRegister rd, FRegister rs1, RoundingMode rounding = RNE);
519 void fcvtds(FRegister rd, FRegister rs1, RoundingMode rounding = RNE);
520 void feqd(Register rd, FRegister rs1, FRegister rs2);
521 void fltd(Register rd, FRegister rs1, FRegister rs2);
522 void fled(Register rd, FRegister rs1, FRegister rs2);
523 void fgtd(Register rd, FRegister rs1, FRegister rs2) { fltd(rd, rs2, rs1); }
524 void fged(Register rd, FRegister rs1, FRegister rs2) { fled(rd, rs2, rs1); }
526 // int32_t <- double
527 void fcvtwd(Register rd, FRegister rs1, RoundingMode rounding = RNE);
528 // uint32_t <- double
529 void fcvtwud(Register rd, FRegister rs1, RoundingMode rounding = RNE);
530 // double <- int32_t
531 void fcvtdw(FRegister rd, Register rs1, RoundingMode rounding = RNE);
532 // double <- uint32_t
533 void fcvtdwu(FRegister rd, Register rs1, RoundingMode rounding = RNE);
534
535 void fmvd(FRegister rd, FRegister rs) { fsgnjd(rd, rs, rs); }
536 void fabsd(FRegister rd, FRegister rs) { fsgnjxd(rd, rs, rs); }
537 void fnegd(FRegister rd, FRegister rs) { fsgnjnd(rd, rs, rs); }
538
539 // ==== RV64D ====
540#if XLEN >= 64
541 // int64_t <- double
542 void fcvtld(Register rd, FRegister rs1, RoundingMode rounding = RNE);
543 // uint64_t <- double
544 void fcvtlud(Register rd, FRegister rs1, RoundingMode rounding = RNE);
545 // xlen <--bit_cast-- double
546 void fmvxd(Register rd, FRegister rs1);
547 // double <- int64_t
548 void fcvtdl(FRegister rd, Register rs1, RoundingMode rounding = RNE);
549 // double <- uint64_t
550 void fcvtdlu(FRegister rd, Register rs1, RoundingMode rounding = RNE);
551 // double <--bit_cast-- xlen
552 void fmvdx(FRegister rd, Register rs1);
553#endif // XLEN >= 64
554
555 // ==== Zba: Address generation ====
556 void adduw(Register rd, Register rs1, Register rs2);
557 void sh1add(Register rd, Register rs1, Register rs2);
558 void sh1adduw(Register rd, Register rs1, Register rs2);
559 void sh2add(Register rd, Register rs1, Register rs2);
560 void sh2adduw(Register rd, Register rs1, Register rs2);
561 void sh3add(Register rd, Register rs1, Register rs2);
562 void sh3adduw(Register rd, Register rs1, Register rs2);
563 void slliuw(Register rd, Register rs1, intx_t imm);
564
565 // ==== Zbb: Basic bit-manipulation ====
566 void andn(Register rd, Register rs1, Register rs2);
567 void orn(Register rd, Register rs1, Register rs2);
568 void xnor(Register rd, Register rs1, Register rs2);
569 void clz(Register rd, Register rs);
570 void clzw(Register rd, Register rs);
571 void ctz(Register rd, Register rs);
572 void ctzw(Register rd, Register rs);
573 void cpop(Register rd, Register rs);
574 void cpopw(Register rd, Register rs);
575 void max(Register rd, Register rs1, Register rs2); // NOLINT
576 void maxu(Register rd, Register rs1, Register rs2);
577 void min(Register rd, Register rs1, Register rs2); // NOLINT
578 void minu(Register rd, Register rs1, Register rs2);
579 void sextb(Register rd, Register rs);
580 void sexth(Register rd, Register rs);
581 void zexth(Register rd, Register rs);
582 void rol(Register rd, Register rs1, Register rs2);
583 void rolw(Register rd, Register rs1, Register rs2);
584 void ror(Register rd, Register rs1, Register rs2);
585 void rori(Register rd, Register rs1, intx_t imm);
586 void roriw(Register rd, Register rs1, intx_t imm);
587 void rorw(Register rd, Register rs1, Register rs2);
588 void orcb(Register rd, Register rs);
589 void rev8(Register rd, Register rs);
590
591 // ==== Zbc: Carry-less multiplication ====
592 void clmul(Register rd, Register rs1, Register rs2);
593 void clmulh(Register rd, Register rs1, Register rs2);
594 void clmulr(Register rd, Register rs1, Register rs2);
595
596 // ==== Zbs: Single-bit instructions ====
597 void bclr(Register rd, Register rs1, Register rs2);
598 void bclri(Register rd, Register rs1, intx_t shamt);
599 void bext(Register rd, Register rs1, Register rs2);
600 void bexti(Register rd, Register rs1, intx_t shamt);
601 void binv(Register rd, Register rs1, Register rs2);
602 void binvi(Register rd, Register rs1, intx_t shamt);
603 void bset(Register rd, Register rs1, Register rs2);
604 void bseti(Register rd, Register rs1, intx_t shamt);
605
606 // ==== Zalasr: Load-acquire, store-release ====
607 void lb(Register rd, Address addr, std::memory_order order);
608 void lh(Register rd, Address addr, std::memory_order order);
609 void lw(Register rd, Address addr, std::memory_order order);
610 void sb(Register rs2, Address addr, std::memory_order order);
611 void sh(Register rs2, Address addr, std::memory_order order);
612 void sw(Register rs2, Address addr, std::memory_order order);
613
614#if XLEN >= 64
615 void ld(Register rd, Address addr, std::memory_order order);
616 void sd(Register rs2, Address addr, std::memory_order order);
617#endif
618
619 // ==== Dart Simulator Debugging ====
621
622 private:
623 // ==== RV32/64C ====
624 void c_lwsp(Register rd, Address addr);
625#if XLEN == 32
626 void c_flwsp(FRegister rd, Address addr);
627#else
628 void c_ldsp(Register rd, Address addr);
629#endif
630 void c_fldsp(FRegister rd, Address addr);
631
632 void c_swsp(Register rs2, Address addr);
633#if XLEN == 32
634 void c_fswsp(FRegister rs2, Address addr);
635#else
636 void c_sdsp(Register rs2, Address addr);
637#endif
638 void c_fsdsp(FRegister rs2, Address addr);
639
640 void c_lw(Register rd, Address addr);
641 void c_ld(Register rd, Address addr);
642 void c_flw(FRegister rd, Address addr);
643 void c_fld(FRegister rd, Address addr);
644
645 void c_sw(Register rs2, Address addr);
646 void c_sd(Register rs2, Address addr);
647 void c_fsw(FRegister rs2, Address addr);
648 void c_fsd(FRegister rs2, Address addr);
649
650 void c_j(Label* label);
651#if XLEN == 32
652 void c_jal(Label* label);
653#endif
654 void c_jr(Register rs1);
655 void c_jalr(Register rs1);
656
657 void c_beqz(Register rs1p, Label* label);
658 void c_bnez(Register rs1p, Label* label);
659
660 void c_li(Register rd, intptr_t imm);
661 void c_lui(Register rd, uintptr_t imm);
662
663 void c_addi(Register rd, Register rs1, intptr_t imm);
664#if XLEN >= 64
665 void c_addiw(Register rd, Register rs1, intptr_t imm);
666#endif
667 void c_addi16sp(Register rd, Register rs1, intptr_t imm);
668 void c_addi4spn(Register rdp, Register rs1, intptr_t imm);
669
670 void c_slli(Register rd, Register rs1, intptr_t imm);
671 void c_srli(Register rd, Register rs1, intptr_t imm);
672 void c_srai(Register rd, Register rs1, intptr_t imm);
673 void c_andi(Register rd, Register rs1, intptr_t imm);
674
675 void c_mv(Register rd, Register rs2);
676
677 void c_add(Register rd, Register rs1, Register rs2);
678 void c_and(Register rd, Register rs1, Register rs2);
679 void c_or(Register rd, Register rs1, Register rs2);
680 void c_xor(Register rd, Register rs1, Register rs2);
681 void c_sub(Register rd, Register rs1, Register rs2);
682#if XLEN >= 64
683 void c_addw(Register rd, Register rs1, Register rs2);
684 void c_subw(Register rd, Register rs1, Register rs2);
685#endif
686
687 void c_nop();
688 void c_ebreak();
689
690 protected:
691 intptr_t UpdateCBOffset(intptr_t branch_position, intptr_t new_offset);
692 intptr_t UpdateCJOffset(intptr_t branch_position, intptr_t new_offset);
693 intptr_t UpdateBOffset(intptr_t branch_position, intptr_t new_offset);
694 intptr_t UpdateJOffset(intptr_t branch_position, intptr_t new_offset);
695 intptr_t UpdateFarOffset(intptr_t branch_position, intptr_t new_offset);
696
697 intptr_t Position() { return buffer_.Size(); }
699 Register rs2,
700 Label* label,
701 Funct3 func,
704 void EmitCBranch(Register rs1p, Label* label, COpcode op);
705 void EmitCJump(Label* label, COpcode op);
706
707 void EmitRType(Funct5 funct5,
708 std::memory_order order,
709 Register rs2,
710 Register rs1,
711 Funct3 funct3,
712 Register rd,
713 Opcode opcode);
714 void EmitRType(Funct7 funct7,
715 Register rs2,
716 Register rs1,
717 Funct3 funct3,
718 Register rd,
719 Opcode opcode);
720 void EmitRType(Funct7 funct7,
721 FRegister rs2,
722 FRegister rs1,
723 Funct3 funct3,
724 FRegister rd,
725 Opcode opcode);
726 void EmitRType(Funct7 funct7,
727 FRegister rs2,
728 FRegister rs1,
730 FRegister rd,
731 Opcode opcode);
732 void EmitRType(Funct7 funct7,
733 FRegister rs2,
734 Register rs1,
736 FRegister rd,
737 Opcode opcode);
738 void EmitRType(Funct7 funct7,
739 FRegister rs2,
740 Register rs1,
741 Funct3 funct3,
742 FRegister rd,
743 Opcode opcode);
744 void EmitRType(Funct7 funct7,
745 FRegister rs2,
746 FRegister rs1,
747 Funct3 funct3,
748 Register rd,
749 Opcode opcode);
750 void EmitRType(Funct7 funct7,
751 FRegister rs2,
752 FRegister rs1,
754 Register rd,
755 Opcode opcode);
756 void EmitRType(Funct7 funct7,
757 intptr_t shamt,
758 Register rs1,
759 Funct3 funct3,
760 Register rd,
761 Opcode opcode);
762
764 Funct2 funct2,
765 FRegister rs2,
766 FRegister rs1,
768 FRegister rd,
769 Opcode opcode);
770
771 void EmitIType(intptr_t imm,
772 Register rs1,
773 Funct3 funct3,
774 Register rd,
775 Opcode opcode);
776 void EmitIType(intptr_t imm,
777 Register rs1,
778 Funct3 funct3,
779 FRegister rd,
780 Opcode opcode);
781
782 void EmitSType(intptr_t imm,
783 Register rs2,
784 Register rs1,
785 Funct3 funct3,
786 Opcode opcode);
787 void EmitSType(intptr_t imm,
788 FRegister rs2,
789 Register rs1,
790 Funct3 funct3,
791 Opcode opcode);
792
793 void EmitBType(intptr_t imm,
794 Register rs2,
795 Register rs1,
796 Funct3 funct3,
797 Opcode opcode);
798
799 void EmitUType(intptr_t imm, Register rd, Opcode opcode);
800
801 void EmitJType(intptr_t imm, Register rd, Opcode opcode);
802
803 uint16_t Read16(intptr_t position) {
804 return buffer_.Load<uint16_t>(position);
805 }
806 void Write16(intptr_t position, uint16_t instruction) {
807 return buffer_.Store<uint16_t>(position, instruction);
808 }
809 void Emit16(uint16_t instruction) {
811 buffer_.Emit<uint16_t>(instruction);
812 }
813 uint32_t Read32(intptr_t position) {
814 return buffer_.Load<uint32_t>(position);
815 }
816 void Write32(intptr_t position, uint32_t instruction) {
817 return buffer_.Store<uint32_t>(position, instruction);
818 }
819
820 public:
821 void Emit32(uint32_t instruction) {
823 buffer_.Emit<uint32_t>(instruction);
824 }
825 void Emit64(uint64_t instruction) {
827 buffer_.Emit<uint64_t>(instruction);
828 }
829
830 protected:
831 ExtensionSet extensions_;
833};
834
835class Assembler : public MicroAssembler {
836 public:
838 intptr_t far_branch_level = 0);
840
843
846
847 void PushRegisters(const RegisterSet& registers);
848 void PopRegisters(const RegisterSet& registers);
849
850 void PushRegistersInOrder(std::initializer_list<Register> regs);
851
853
854 // Push all registers which are callee-saved according to the ARM64 ABI.
856
857 // Pop all registers which are callee-saved according to the ARM64 ABI.
859
860 void ExtendValue(Register rd, Register rn, OperandSize sz) override;
862 Register rn,
863 OperandSize sz = kWordBytes) override;
864
865 void Drop(intptr_t stack_elements) {
866 ASSERT(stack_elements >= 0);
867 if (stack_elements > 0) {
868 AddImmediate(SP, SP, stack_elements * target::kWordSize);
869 }
870 }
871
872 void Bind(Label* label) override { MicroAssembler::Bind(label); }
873 // Unconditional jump to a given label.
875 j(label, distance);
876 }
877 // Unconditional jump to a given address in register.
879 // Unconditional jump to a given address in memory. Clobbers TMP.
880 void Jump(const Address& address);
881
884 }
887 }
888
891
893 const Address& address,
894 OperandSize size = kWordBytes) override;
895
897 const Address& address,
898 OperandSize size = kWordBytes) override;
899
901 Address address,
902 OperandSize size = kWordBytes) override;
903
904 // Debugging and bringup support.
905 void Breakpoint() override { trap(); }
906
908 if (prologue_offset_ == -1) {
910 }
911 }
912
913 void ReserveAlignedFrameSpace(intptr_t frame_space);
914
915 // In debug mode, this generates code to check that:
916 // FP + kExitLinkSlotFromEntryFp == SP
917 // or triggers breakpoint otherwise.
919
920 // Instruction pattern from entrypoint is used in Dart frame prologs
921 // to set up the frame and save a PC which can be used to figure out the
922 // RawInstruction object corresponding to the code running in the frame.
923 static constexpr intptr_t kEntryPointToPcMarkerOffset = 0;
924 static intptr_t EntryPointToPcMarkerOffset() {
926 }
927
928 // On some other platforms, we draw a distinction between safe and unsafe
929 // smis.
930 static bool IsSafe(const Object& object) { return true; }
931 static bool IsSafeSmi(const Object& object) { return target::IsSmi(object); }
932
936
937 // Branches to the given label if the condition holds.
938 void BranchIf(Condition condition,
939 Label* label,
942 Label* label,
945 intptr_t bit_number,
946 Condition condition,
947 Label* label,
949 void SetIf(Condition condition, Register rd);
950
951 void SmiUntag(Register reg) { SmiUntag(reg, reg); }
953 void SmiTag(Register reg) override { SmiTag(reg, reg); }
955
956 // Truncates upper bits.
958 if (result == value) {
959 ASSERT(TMP != value);
961 value = TMP;
962 }
963 ASSERT(value != result);
969 Bind(&done);
970 }
971
972#if XLEN != 32
974 if (result == value) {
975 ASSERT(TMP != value);
977 value = TMP;
978 }
979 ASSERT(value != result);
984 Bind(&done);
985 }
986#endif
987
989 Label* label,
992 Label* label,
993 JumpDistance distance = kFarJump) override;
994
995 void ArithmeticShiftRightImmediate(Register reg, intptr_t shift) override;
997 Register reg2,
998 intptr_t offset,
1000 Register temp,
1001 Label* equals) override;
1002
1003 void JumpAndLink(const Code& code,
1009
1011 const Code& code,
1016 snapshot_behavior);
1017 }
1018
1019 // Emit a call that shares its object pool entries with other calls
1020 // that have the same equivalence marker.
1022 const Code& code,
1023 const Object& equivalence,
1025
1028 void Call(const Code& code) { JumpAndLink(code); }
1029
1032
1033 void AddImmediate(Register dest, intx_t imm) {
1034 AddImmediate(dest, dest, imm);
1035 }
1037 intx_t imm,
1038 OperandSize width = kWordBytes) override {
1039 MulImmediate(dest, dest, imm, width);
1040 }
1043 Register base,
1044 Register index,
1046 int32_t disp) override {
1047 if (base == kNoRegister || base == ZR) {
1048 if (scale == TIMES_1) {
1049 AddImmediate(dest, index, disp);
1050 } else {
1051 slli(dest, index, scale);
1052 AddImmediate(dest, disp);
1053 }
1054 } else {
1055 AddShifted(dest, base, index, scale);
1056 AddImmediate(dest, disp);
1057 }
1058 }
1059 void AddShifted(Register dest, Register base, Register index, intx_t shift);
1061
1062 // Macros accepting a pp Register argument may attempt to load values from
1063 // the object pool when possible. Unless you are sure that the untagged object
1064 // pool pointer is in another register, or that it is not available at all,
1065 // PP should be passed for pp. `dest` can be TMP2, `rn` cannot. `dest` can be
1066 // TMP.
1068 Register rn,
1069 intx_t imm,
1070 OperandSize sz = kWordBytes);
1072 Register rn,
1073 intx_t imm,
1076 Register rn,
1077 intx_t imm,
1078 OperandSize sz = kWordBytes);
1079 void AndImmediate(Register rd, intx_t imm) override {
1080 AndImmediate(rd, rd, imm);
1081 }
1083 Register src1,
1084 Register src2 = kNoRegister) override {
1085 ASSERT(src1 != src2); // Likely a mistake.
1086 if (src2 == kNoRegister) {
1087 src2 = dst;
1088 }
1089 and_(dst, src2, src1);
1090 }
1092 Register rn,
1093 intx_t imm,
1094 OperandSize sz = kWordBytes);
1095 void OrImmediate(Register rd, intx_t imm) { OrImmediate(rd, rd, imm); }
1097 Register rn,
1098 intx_t imm,
1099 OperandSize sz = kWordBytes);
1100 void LslImmediate(Register rd, int32_t shift) { slli(rd, rd, shift); }
1101 void LslRegister(Register dst, Register shift) override {
1102 sll(dst, dst, shift);
1103 }
1104 void LsrImmediate(Register rd, int32_t shift) override {
1105 srli(rd, rd, shift);
1106 }
1107 void TestImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
1109 intx_t imm,
1110 OperandSize sz = kWordBytes) override;
1111
1115 const Address& address,
1116 OperandSize sz = kWordBytes) override;
1117 // For loading indexed payloads out of tagged objects like Arrays. If the
1118 // payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
1119 // [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
1121 Register base,
1122 int32_t payload_offset,
1123 Register index,
1125 OperandSize sz = kWordBytes) override;
1130 }
1133 }
1134
1135 void LoadFromStack(Register dst, intptr_t depth);
1136 void StoreToStack(Register src, intptr_t depth);
1137 void CompareToStack(Register src, intptr_t depth);
1138
1140 const Address& address,
1141 OperandSize sz = kWordBytes) override;
1142 void StoreZero(const Address& address, Register temp = kNoRegister) {
1143 Store(ZR, address);
1144 }
1148 }
1152 }
1153
1156 }
1159 }
1161
1163 // No single register SIMD on RISC-V.
1164 UNREACHABLE();
1165 }
1167 // No single register SIMD on RISC-V.
1168 UNREACHABLE();
1169 }
1171 // No single register SIMD on RISC-V.
1172 UNREACHABLE();
1173 }
1174
1177 CanBeSmi can_value_be_smi,
1178 Register scratch) override;
1180 Register slot,
1182 CanBeSmi can_value_be_smi,
1183 Register scratch) override;
1185
1187 Register object,
1188 const Address& dest,
1189 const Object& value,
1190 MemoryOrder memory_order = kRelaxedNonAtomic,
1191 OperandSize size = kWordBytes) override;
1192
1193 // Stores a non-tagged value into a heap object.
1195 const Address& dest,
1196 Register value);
1197
1198 // Object pool, loading from pool, etc.
1200
1201 bool constant_pool_allowed() const { return constant_pool_allowed_; }
1202 void set_constant_pool_allowed(bool b) { constant_pool_allowed_ = b; }
1203
1204 bool CanLoadFromObjectPool(const Object& object) const;
1206 const ExternalLabel* label,
1210
1211 // Note: the function never clobbers TMP, TMP2 scratch registers.
1212 void LoadObject(Register dst, const Object& obj) {
1213 LoadObjectHelper(dst, obj, false);
1214 }
1215 // Note: the function never clobbers TMP, TMP2 scratch registers.
1217 Register dst,
1218 const Object& obj,
1221 LoadObjectHelper(dst, obj, true, snapshot_behavior);
1222 }
1223 // Note: the function never clobbers TMP, TMP2 scratch registers.
1224 void LoadImmediate(Register reg, intx_t imm) override;
1225
1226 void LoadSImmediate(FRegister reg, float imms);
1227 void LoadDImmediate(FRegister reg, double immd);
1229
1230 // Load word from pool from the given offset using encoding that
1231 // InstructionPattern::DecodeLoadWordFromPool can decode.
1232 //
1233 // Note: the function never clobbers TMP, TMP2 scratch registers.
1234 void LoadWordFromPoolIndex(Register dst, intptr_t index, Register pp = PP);
1235
1236 // Store word to pool at the given offset.
1237 //
1238 // Note: clobbers TMP, does not clobber TMP2.
1239 void StoreWordToPoolIndex(Register src, intptr_t index, Register pp = PP);
1240
1241 void PushObject(const Object& object) {
1242 if (IsSameObject(compiler::NullObject(), object)) {
1244 } else if (target::IsSmi(object) && (target::ToRawSmi(object) == 0)) {
1246 } else {
1247 LoadObject(TMP, object);
1249 }
1250 }
1251 void PushImmediate(int64_t immediate) {
1252 if (immediate == 0) {
1254 } else {
1255 LoadImmediate(TMP, immediate);
1257 }
1258 }
1259 void CompareObject(Register reg, const Object& object);
1260
1263
1265 Register temp,
1266 intptr_t low,
1267 intptr_t high,
1268 RangeCheckCondition condition,
1269 Label* target) override;
1270
1274 intptr_t class_id,
1275 Register scratch = kNoRegister);
1276 // Note: input and output registers must be different.
1280 Register src,
1281 Register scratch,
1282 bool can_be_null = false) override;
1283
1284 void EnterFrame(intptr_t frame_size);
1286 void Ret() { ret(); }
1287
1288 // Sets the return address to [value] as if there was a call.
1289 // On RISC-V sets RA.
1291
1292 // Emit code to transition between generated mode and native mode.
1293 //
1294 // These require and ensure that CSP and SP are equal and aligned and require
1295 // a scratch register (in addition to TMP/TMP2).
1296
1297 void TransitionGeneratedToNative(Register destination_address,
1298 Register new_exit_frame,
1299 Register new_exit_through_ffi,
1300 bool enter_safepoint);
1302 bool exit_safepoint,
1303 bool ignore_unwind_in_progress = false,
1304 bool set_tag = true);
1306 void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress);
1307
1308 void CheckFpSpDist(intptr_t fp_sp_dist);
1309
1313
1314 // Restores the values of the registers that are blocked to cache some values
1315 // e.g. WRITE_BARRIER_STATE and NULL_REG.
1317
1319
1320 void EnterDartFrame(intptr_t frame_size, Register new_pp = kNoRegister);
1321 void EnterOsrFrame(intptr_t extra_size, Register new_pp = kNoRegister);
1323 void LeaveDartFrame(intptr_t fp_sp_dist);
1324
1325 // For non-leaf runtime calls. For leaf runtime calls, use LeafRuntimeScope,
1326 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
1327
1328 // Set up a stub frame so that the stack traversal code can easily identify
1329 // a stub frame.
1332
1333 // Set up a frame for calling a C function.
1334 // Automatically save the pinned registers in Dart which are not callee-
1335 // saved in the native calling convention.
1336 // Use together with CallCFunction.
1337 void EnterCFrame(intptr_t frame_space);
1339
1343
1344 void CombineHashes(Register dst, Register other) override;
1345 void FinalizeHashForSize(intptr_t bit_size,
1346 Register dst,
1347 Register scratch = TMP) override;
1348
1349 // If allocation tracing for |cid| is enabled, will jump to |trace| label,
1350 // which will allocate in the runtime where tracing occurs.
1352 Label* trace,
1353 Register temp_reg,
1354 JumpDistance distance = JumpDistance::kFarJump);
1355
1357 Label* trace,
1358 Register temp_reg,
1359 JumpDistance distance = JumpDistance::kFarJump);
1360
1361 void TryAllocateObject(intptr_t cid,
1362 intptr_t instance_size,
1363 Label* failure,
1365 Register instance_reg,
1366 Register temp_reg) override;
1367
1368 void TryAllocateArray(intptr_t cid,
1369 intptr_t instance_size,
1370 Label* failure,
1372 Register end_address,
1373 Register temp1,
1374 Register temp2);
1375
1377#if defined(DEBUG)
1378 Label okay;
1379 lx(tmp, Address(top, 0));
1380 subi(tmp, tmp, kAllocationCanary);
1381 beqz(tmp, &okay, Assembler::kNearJump);
1382 Stop("Allocation canary");
1383 Bind(&okay);
1384#endif
1385 }
1387#if defined(DEBUG)
1388 ASSERT(top != TMP);
1390 sx(TMP, Address(top, 0));
1391#endif
1392 }
1393
1394 // Copy [size] bytes from [src] address to [dst] address.
1395 // [size] should be a multiple of word size.
1396 // Clobbers [src], [dst], [size] and [temp] registers.
1398 Register dst,
1399 Register size,
1400 Register temp);
1401
1402 // This emits an PC-relative call of the form "bl <offset>". The offset
1403 // is not yet known and needs therefore relocation to the right place before
1404 // the code can be used.
1405 //
1406 // The necessary information for the "linker" (i.e. the relocation
1407 // information) is stored in [UntaggedCode::static_calls_target_table_]: an
1408 // entry of the form
1409 //
1410 // (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
1411 //
1412 // will be used during relocation to fix the offset.
1413 //
1414 // The provided [offset_into_target] will be added to calculate the final
1415 // destination. It can be used e.g. for calling into the middle of a
1416 // function.
1417 void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
1418
1419 // This emits an PC-relative tail call of the form "b <offset>".
1420 //
1421 // See also above for the pc-relative call.
1422 void GenerateUnRelocatedPcRelativeTailCall(intptr_t offset_into_target = 0);
1423
1424 static bool AddressCanHoldConstantIndex(const Object& constant,
1425 bool is_external,
1426 intptr_t cid,
1427 intptr_t index_scale);
1428
1430 intptr_t cid,
1431 intptr_t index_scale,
1432 Register array,
1433 intptr_t index) const;
1435 bool is_external,
1436 intptr_t cid,
1437 intptr_t index_scale,
1438 Register array,
1439 intptr_t index);
1441 intptr_t cid,
1442 intptr_t index_scale,
1443 bool index_unboxed,
1444 Register array,
1445 Register index,
1446 Register temp);
1447
1449 bool is_external,
1450 intptr_t cid,
1451 intptr_t index_scale,
1452 bool index_unboxed,
1453 Register array,
1454 Register index);
1455
1457 Register field,
1458 Register scratch,
1459 bool is_shared);
1460
1463 Register offset_in_words_as_smi) override;
1464
1467 int32_t offset) override {
1469 }
1470
1471 // Returns object data offset for address calculation; for heap objects also
1472 // accounts for the tag.
1473 static int32_t HeapDataOffset(bool is_external, intptr_t cid) {
1474 return is_external
1475 ? 0
1477 }
1478
1480 Register rs1,
1481 intx_t imm,
1482 Label* overflow);
1484 Register rs1,
1485 intx_t imm,
1486 Label* overflow);
1488 Register rs1,
1489 intx_t imm,
1490 Label* overflow);
1492 Register rs1,
1493 Register rs2,
1494 Label* overflow);
1496 Register rs1,
1497 Register rs2,
1498 Label* overflow);
1500 Register rs1,
1501 Register rs2,
1502 Label* overflow);
1503
1504 // Clobbers [rs].
1506
1507 private:
1508 bool constant_pool_allowed_;
1509
1510 enum DeferredCompareType {
1511 kNone,
1512 kCompareReg,
1513 kCompareImm,
1514 kTestReg,
1515 kTestImm,
1516 };
1517 DeferredCompareType deferred_compare_ = kNone;
1518 Register deferred_left_ = kNoRegister;
1519 Register deferred_reg_ = kNoRegister;
1520 intptr_t deferred_imm_ = 0;
1521
1522 // Note: the function never clobbers TMP, TMP2 scratch registers.
1523 void LoadObjectHelper(
1524 Register dst,
1525 const Object& obj,
1526 bool is_unique,
1529
1530 void JumpAndLink(intptr_t target_code_pool_index, CodeEntryKind entry_kind);
1531
1532 friend class dart::FlowGraphCompiler;
1533 std::function<void(Register reg)> generate_invoke_write_barrier_wrapper_;
1534 std::function<void()> generate_invoke_array_write_barrier_;
1535
1536 DISALLOW_ALLOCATION();
1537 DISALLOW_COPY_AND_ASSIGN(Assembler);
1538};
1539
1540} // namespace compiler
1541} // namespace dart
1542
1543#endif // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_RISCV_H_
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:263
int count
Definition: FontMgrTest.cpp:50
static void round(SkPoint *p)
bool equals(SkDrawable *a, SkDrawable *b)
#define UNREACHABLE()
Definition: assert.h:248
Register base() const
Address(Register base, Register index)=delete
Address(Register base, intptr_t offset)
intptr_t offset() const
void Stop(const char *message)
ObjectPoolBuilder & object_pool_builder()
void Store(intptr_t position, T value)
void PushRegistersInOrder(std::initializer_list< Register > regs)
void StoreDToOffset(FRegister src, Register base, int32_t offset)
void PopRegisterPair(Register r0, Register r1)
void MoveUnboxedDouble(FpuRegister dst, FpuRegister src)
void LoadClassId(Register result, Register object)
void AndImmediate(Register rd, intx_t imm) override
void LoadPoolPointer(Register pp=PP)
void Call(Address target)
bool CanLoadFromObjectPool(const Object &object) const
void CompareClassId(Register object, intptr_t class_id, Register scratch=kNoRegister)
void AddImmediate(Register dest, intx_t imm)
void PushRegisters(const RegisterSet &registers)
void LoadSFromOffset(SRegister reg, Register base, int32_t offset, Condition cond=AL)
void StoreUnboxedDouble(FpuRegister src, Register base, int32_t offset)
void CompareObject(Register reg, const Object &object)
void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src)
void BranchIfZero(Register rn, Label *label, JumpDistance distance=kFarJump)
void LoadUniqueObject(Register dst, const Object &obj, ObjectPoolBuilderEntry::SnapshotBehavior snapshot_behavior=ObjectPoolBuilderEntry::kSnapshotable)
void LoadObject(Register dst, const Object &obj)
void CombineHashes(Register dst, Register other) override
void BranchIfSmi(Register reg, Label *label, JumpDistance distance=kFarJump) override
void LoadTaggedClassIdMayBeSmi(Register result, Register object)
void Call(const Code &code)
void LoadDFromOffset(DRegister reg, Register base, int32_t offset, Condition cond=AL)
void TransitionNativeToGenerated(Register scratch, bool exit_safepoint, bool ignore_unwind_in_progress=false, bool set_tag=true)
void TsanLoadAcquire(Register addr)
void ComputeElementAddressForIntIndex(Register address, bool is_external, intptr_t cid, intptr_t index_scale, Register array, intptr_t index)
void PushRegisterPair(Register r0, Register r1)
void StoreZero(const Address &address, Register temp=kNoRegister)
Address ElementAddressForRegIndex(bool is_external, intptr_t cid, intptr_t index_scale, bool index_unboxed, Register array, Register index, Register temp)
void LoadIndexedPayload(Register dest, Register base, int32_t payload_offset, Register index, ScaleFactor scale, OperandSize sz=kWordBytes) override
void SetIf(Condition condition, Register rd)
Assembler(ObjectPoolBuilder *object_pool_builder, intptr_t far_branch_level=0)
void EnterFrame(intptr_t frame_size)
void LoadImmediate(Register reg, intx_t imm) override
void LoadFieldFromOffset(Register reg, Register base, int32_t offset, OperandSize type=kFourBytes) override
void CheckAllocationCanary(Register top, Register tmp=TMP)
void j(Condition condition, Label *label, JumpDistance distance=kFarJump)
void SmiUntag(Register reg)
void TryAllocateObject(intptr_t cid, intptr_t instance_size, Label *failure, JumpDistance distance, Register instance_reg, Register temp_reg) override
void Jump(Label *label, JumpDistance distance=kFarJump)
void StoreWordToPoolIndex(Register src, intptr_t index, Register pp=PP)
void LoadDImmediate(FRegister reg, double immd)
void CompareObjectRegisters(Register rn, Register rm)
void LoadFromStack(Register dst, intptr_t depth)
void EnterDartFrame(intptr_t frame_size, bool load_pool_pointer=true)
void EnterOsrFrame(intptr_t extra_size, Register new_pp=kNoRegister)
Address ElementAddressForIntIndex(bool is_external, intptr_t cid, intptr_t index_scale, Register array, intptr_t index) const
void PushRegister(Register r)
void LoadMemoryValue(Register dst, Register base, int32_t offset)
void b(Label *label, Condition cond=AL)
void Store(Register src, const Address &address, OperandSize sz=kWordBytes) override
void set_constant_pool_allowed(bool b)
void StoreDFieldToOffset(FRegister src, Register base, int32_t offset)
Address PrepareLargeOffset(Register base, int32_t offset)
static bool AddressCanHoldConstantIndex(const Object &constant, bool is_external, intptr_t cid, intptr_t index_scale)
void MultiplyBranchOverflow(Register rd, Register rs1, Register rs2, Label *overflow)
void StoreObjectIntoObjectNoBarrier(Register object, const Address &dest, const Object &value, MemoryOrder memory_order=kRelaxedNonAtomic, OperandSize size=kWordBytes) override
void EnterDartFrame(intptr_t frame_size, Register new_pp=kNoRegister)
void EnterFullSafepoint(Register scratch)
void LoadClassById(Register result, Register class_id)
void StoreSToOffset(FRegister src, Register base, int32_t offset)
void PushValueAtOffset(Register base, int32_t offset)
void LoadIsolate(Register dst)
void LoadAcquire(Register dst, const Address &address, OperandSize size=kWordBytes) override
void LsrImmediate(Register rd, int32_t shift) override
void SetReturnAddress(Register value)
void AddShifted(Register dest, Register base, Register index, intx_t shift)
void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target=0)
void XorImmediate(Register rd, Register rn, intx_t imm, OperandSize sz=kWordBytes)
void LoadSFromOffset(FRegister dest, Register base, int32_t offset)
void LoadInt32FromBoxOrSmi(Register result, Register value) override
void BranchIf(Condition condition, Label *label, JumpDistance distance=kFarJump)
void PushObject(const Object &object)
void ComputeElementAddressForRegIndex(Register address, bool is_external, intptr_t cid, intptr_t index_scale, bool index_unboxed, Register array, Register index)
void AndRegisters(Register dst, Register src1, Register src2=kNoRegister) override
void PushImmediate(int64_t immediate)
void LoadDFromOffset(FRegister dest, Register base, int32_t offset)
void CompareWithMemoryValue(Register value, Address address, OperandSize size=kWordBytes) override
void LoadWordFromPoolIndex(Register dst, intptr_t index, Register pp=PP)
void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset)
void StoreMemoryValue(Register src, Register base, int32_t offset)
void LoadSFieldFromOffset(FRegister dest, Register base, int32_t offset)
void TransitionGeneratedToNative(Register destination_address, Register new_exit_frame, Register new_exit_through_ffi, bool enter_safepoint)
void AddImmediate(Register dest, Register rn, intx_t imm, OperandSize sz=kWordBytes)
void StoreToStack(Register src, intptr_t depth)
void Call(Register target)
void AddScaled(Register dest, Register base, Register index, ScaleFactor scale, int32_t disp) override
void LoadStaticFieldAddress(Register address, Register field, Register scratch, bool is_shared)
void SubRegisters(Register dest, Register src)
void PopRegisters(const RegisterSet &registers)
void StoreInternalPointer(Register object, const Address &dest, Register value)
void MulImmediate(Register reg, int32_t imm, OperandSize width=kFourBytes) override
void AddRegisters(Register dest, Register src)
void MulImmediate(Register dest, intx_t imm, OperandSize width=kWordBytes) override
void Bind(Label *label) override
void ReserveAlignedFrameSpace(intptr_t frame_space)
static intptr_t EntryPointToPcMarkerOffset()
void RangeCheck(Register value, Register temp, intptr_t low, intptr_t high, RangeCheckCondition condition, Label *target) override
void Load(Register dest, const Address &address, OperandSize sz=kWordBytes) override
void AndImmediate(Register rd, Register rn, intx_t imm, OperandSize sz=kWordBytes)
void PopRegister(Register r)
void AddImmediateBranchOverflow(Register rd, Register rs1, intx_t imm, Label *overflow)
void LslRegister(Register dst, Register shift) override
void add(Register rd, Register rn, Operand o, Condition cond=AL)
void Call(Address target, Condition cond=AL)
void CallCFunction(Register target)
void StoreSToOffset(SRegister reg, Register base, int32_t offset, Condition cond=AL)
void WriteAllocationCanary(Register top)
void CallRuntime(const RuntimeEntry &entry, intptr_t argument_count)
void ExtractInstanceSizeFromTags(Register result, Register tags)
void LoadObject(Register rd, const Object &object, Condition cond=AL)
void CompareRegisters(Register rn, Register rm)
void ArrayStoreBarrier(Register object, Register slot, Register value, CanBeSmi can_value_be_smi, Register scratch) override
void CompareToStack(Register src, intptr_t depth)
void LoadImmediate(Register rd, Immediate value, Condition cond=AL)
void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond=AL)
void LoadFromOffset(Register reg, Register base, int32_t offset, OperandSize type=kFourBytes) override
void Jump(const Address &address)
void ExtendValue(Register rd, Register rn, OperandSize sz) override
void StoreBarrier(Register object, Register value, CanBeSmi can_value_be_smi, Register scratch) override
void MaybeTraceAllocation(intptr_t cid, Label *trace, Register temp_reg, JumpDistance distance=JumpDistance::kFarJump)
void TestImmediate(Register rn, intx_t imm, OperandSize sz=kWordBytes)
static bool IsSafeSmi(const Object &object)
void and_(Register rd, Register rn, Operand o, Condition cond=AL)
static int32_t HeapDataOffset(bool is_external, intptr_t cid)
void Drop(intptr_t stack_elements)
void StoreUnboxedSimd128(FpuRegister src, Register base, int32_t offset)
void EnterCFrame(intptr_t frame_space)
void OrImmediate(Register rd, Register rn, intx_t imm, OperandSize sz=kWordBytes)
void VerifyStoreNeedsNoWriteBarrier(Register object, Register value) override
void MulImmediate(Register dest, Register rn, intx_t imm, OperandSize width=kWordBytes)
void CompareWords(Register reg1, Register reg2, intptr_t offset, Register count, Register temp, Label *equals) override
void AddBranchOverflow(Register rd, Register rs1, Register rs2, Label *overflow)
Address PrepareAtomicOffset(Register base, int32_t offset)
void BranchIfNotSmi(Register reg, Label *label, JumpDistance distance=kFarJump)
void GenerateUnRelocatedPcRelativeTailCall(intptr_t offset_into_target=0)
void LoadInt64FromBoxOrSmi(Register result, Register value) override
void CallCFunction(Address target)
static bool IsSafe(const Object &object)
void BranchIfBit(Register rn, intptr_t bit_number, Condition condition, Label *label, JumpDistance distance=kFarJump)
void SubtractBranchOverflow(Register rd, Register rs1, Register rs2, Label *overflow)
void Jump(Register target)
void LoadClassIdMayBeSmi(Register result, Register object)
void JumpAndLinkPatchable(const Code &code, CodeEntryKind entry_kind=CodeEntryKind::kNormal, ObjectPoolBuilderEntry::SnapshotBehavior snapshot_behavior=ObjectPoolBuilderEntry::kSnapshotable)
void ExtendAndSmiTagValue(Register rd, Register rn, OperandSize sz=kWordBytes) override
void JumpAndLinkWithEquivalence(const Code &code, const Object &equivalence, CodeEntryKind entry_kind=CodeEntryKind::kNormal)
void OrImmediate(Register rd, intx_t imm)
void LoadUnboxedDouble(FpuRegister dst, Register base, int32_t offset)
void CountLeadingZeroes(Register rd, Register rs)
void LoadIsolateGroup(Register dst)
void LoadFieldAddressForRegOffset(Register address, Register instance, Register offset_in_words_as_smi) override
void MultiplyImmediateBranchOverflow(Register rd, Register rs1, intx_t imm, Label *overflow)
void BranchOnMonomorphicCheckedEntryJIT(Label *label)
void Store(Register reg, const Address &address, OperandSize type, Condition cond)
void StoreSFieldToOffset(FRegister src, Register base, int32_t offset)
void SmiUntag(Register reg, Condition cond=AL)
void MoveRegister(Register rd, Register rm, Condition cond)
void CompareImmediate(Register rn, intx_t imm, OperandSize sz=kWordBytes) override
void TsanStoreRelease(Register addr)
void sub(Register rd, Register rn, Operand o, Condition cond=AL)
void LoadFieldAddressForOffset(Register address, Register instance, int32_t offset) override
void LoadDFieldFromOffset(FRegister dest, Register base, int32_t offset)
void TryAllocateArray(intptr_t cid, intptr_t instance_size, Label *failure, Register instance, Register end_address, Register temp1, Register temp2)
void TestRegisters(Register rn, Register rm)
void StoreToOffset(Register reg, Register base, int32_t offset, OperandSize type=kFourBytes) override
void ExtractClassIdFromTags(Register result, Register tags)
void LeaveDartFrame(intptr_t fp_sp_dist)
void MaybeTraceAllocation(Register cid, Label *trace, Register temp_reg, JumpDistance distance=JumpDistance::kFarJump)
void JumpAndLink(const Code &code, ObjectPoolBuilderEntry::Patchability patchable=ObjectPoolBuilderEntry::kNotPatchable, CodeEntryKind entry_kind=CodeEntryKind::kNormal, ObjectPoolBuilderEntry::SnapshotBehavior snapshot_behavior=ObjectPoolBuilderEntry::kSnapshotable)
void FinalizeHashForSize(intptr_t bit_size, Register dst, Register scratch=TMP) override
void SmiUntag(Register dst, Register src)
void EnsureHasClassIdInDEBUG(intptr_t cid, Register src, Register scratch, bool can_be_null=false) override
void LslImmediate(Register rd, int32_t shift)
void SmiTag(Register dst, Register src)
void LoadQImmediate(FRegister reg, simd128_value_t immq)
void SubtractImmediateBranchOverflow(Register rd, Register rs1, intx_t imm, Label *overflow)
void StoreDToOffset(DRegister reg, Register base, int32_t offset, Condition cond=AL)
void CheckFpSpDist(intptr_t fp_sp_dist)
void AddImmediate(Register rd, int32_t value, Condition cond=AL)
void LoadSImmediate(FRegister reg, float imms)
void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress)
void LoadNativeEntry(Register dst, const ExternalLabel *label, ObjectPoolBuilderEntry::Patchability patchable)
void CopyMemoryWords(Register src, Register dst, Register size, Register temp)
void StoreRelease(Register src, const Address &address, OperandSize size=kWordBytes) override
static constexpr intptr_t kEntryPointToPcMarkerOffset
void SmiTag(Register reg) override
void ArithmeticShiftRightImmediate(Register reg, intptr_t shift) override
FieldAddress(Register base, Register index)=delete
FieldAddress(Register base, intptr_t offset)
void clmulh(Register rd, Register rs1, Register rs2)
void li(Register rd, intptr_t imm)
void fmvwx(FRegister rd, Register rs1)
void ctzw(Register rd, Register rs)
void csrw(uint32_t csr, Register rs)
void fsw(FRegister rs2, Address addr)
void csrc(uint32_t csr, Register rs)
void div(Register rd, Register rs1, Register rs2)
void scw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
uint32_t Read32(intptr_t position)
void jr(Register rs1, intptr_t offset=0)
intptr_t UpdateCBOffset(intptr_t branch_position, intptr_t new_offset)
void csrci(uint32_t csr, uint32_t imm)
void set_far_branch_level(intptr_t level)
void sh2adduw(Register rd, Register rs1, Register rs2)
void flts(Register rd, FRegister rs1, FRegister rs2)
void fabss(FRegister rd, FRegister rs)
void sh1adduw(Register rd, Register rs1, Register rs2)
void blt(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void binv(Register rd, Register rs1, Register rs2)
void not_(Register rd, Register rs)
void flw(FRegister rd, Address addr)
void sb(Register rs2, Address addr)
void sgtz(Register rd, Register rs)
void lui(Register rd, intptr_t imm)
void fmsubs(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void fled(Register rd, FRegister rs1, FRegister rs2)
void fsgnjd(FRegister rd, FRegister rs1, FRegister rs2)
void rorw(Register rd, Register rs1, Register rs2)
void clmulr(Register rd, Register rs1, Register rs2)
void csrr(Register rd, uint32_t csr)
void Emit32(uint32_t instruction)
void amoorw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void roriw(Register rd, Register rs1, intx_t imm)
void fgts(Register rd, FRegister rs1, FRegister rs2)
void bleu(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void fnmadds(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void sw(Register rs2, Address addr)
void sh3add(Register rd, Register rs1, Register rs2)
void EmitBType(intptr_t imm, Register rs2, Register rs1, Funct3 funct3, Opcode opcode)
void slliuw(Register rd, Register rs1, intx_t imm)
void jalr(Register rd, Register rs1, intptr_t offset=0)
void mul(Register rd, Register rs1, Register rs2)
void EmitRType(Funct7 funct7, Register rs2, Register rs1, Funct3 funct3, Register rd, Opcode opcode)
void fsgnjns(FRegister rd, FRegister rs1, FRegister rs2)
void SimulatorPrintObject(Register rs1)
void fnegs(FRegister rd, FRegister rs)
void bext(Register rd, Register rs1, Register rs2)
void csrsi(uint32_t csr, uint32_t imm)
void EmitRType(Funct7 funct7, FRegister rs2, FRegister rs1, Funct3 funct3, Register rd, Opcode opcode)
void EmitRType(Funct7 funct7, FRegister rs2, Register rs1, Funct3 funct3, FRegister rd, Opcode opcode)
void lb(Register rd, Address addr, std::memory_order order)
void rev8(Register rd, Register rs)
void sltz(Register rd, Register rs)
void sw(Register rs2, Address addr, std::memory_order order)
void amoaddw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void feqs(Register rd, FRegister rs1, FRegister rs2)
void fmaxs(FRegister rd, FRegister rs1, FRegister rs2)
void csrrc(Register rd, uint32_t csr, Register rs1)
void fnegd(FRegister rd, FRegister rs)
void bclr(Register rd, Register rs1, Register rs2)
void rori(Register rd, Register rs1, intx_t imm)
bool Supports(Extension extension) const
void bne(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void mulh(Register rd, Register rs1, Register rs2)
void fcvtdwu(FRegister rd, Register rs1, RoundingMode rounding=RNE)
uint16_t Read16(intptr_t position)
void jal(Register rd, Label *label, JumpDistance d=kFarJump)
void jal(Label *label, JumpDistance d=kFarJump)
void Emit16(uint16_t instruction)
void xnor(Register rd, Register rs1, Register rs2)
void bset(Register rd, Register rs1, Register rs2)
void auipc(Register rd, intptr_t imm)
void fnmsubs(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void amomaxw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void andn(Register rd, Register rs1, Register rs2)
void fcvtwus(Register rd, FRegister rs1, RoundingMode rounding=RNE)
void sltu(Register rd, Register rs1, Register rs2)
void blez(Register rs, Label *label, JumpDistance distance=kFarJump)
void csrs(uint32_t csr, Register rs)
void fcvtdw(FRegister rd, Register rs1, RoundingMode rounding=RNE)
void EmitRType(Funct7 funct7, FRegister rs2, FRegister rs1, RoundingMode round, Register rd, Opcode opcode)
void seqz(Register rd, Register rs)
void fsubd(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void fged(Register rd, FRegister rs1, FRegister rs2)
void lbu(Register rd, Address addr)
void maxu(Register rd, Register rs1, Register rs2)
void feqd(Register rd, FRegister rs1, FRegister rs2)
void lhu(Register rd, Address addr)
void lb(Register rd, Address addr)
bool Supports(ExtensionSet extensions) const
void fnmaddd(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void srl(Register rd, Register rs1, Register rs2)
void mulhsu(Register rd, Register rs1, Register rs2)
void clz(Register rd, Register rs)
void amoxorw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void bexti(Register rd, Register rs1, intx_t shamt)
void fclassd(Register rd, FRegister rs1)
void amominuw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void Emit64(uint64_t instruction)
void bseti(Register rd, Register rs1, intx_t shamt)
void fmadds(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void fcvtws(Register rd, FRegister rs1, RoundingMode rounding=RNE)
void mv(Register rd, Register rs)
void csrrci(Register rd, uint32_t csr, uint32_t imm)
void EmitRType(Funct7 funct7, FRegister rs2, Register rs1, RoundingMode round, FRegister rd, Opcode opcode)
void fabsd(FRegister rd, FRegister rs)
void csrrsi(Register rd, uint32_t csr, uint32_t imm)
intptr_t UpdateCJOffset(intptr_t branch_position, intptr_t new_offset)
void jalr_fixed(Register rd, Register rs1, intptr_t offset)
void mulhu(Register rd, Register rs1, Register rs2)
void snez(Register rd, Register rs)
void orcb(Register rd, Register rs)
void bgtz(Register rs, Label *label, JumpDistance distance=kFarJump)
void fsgnjxs(FRegister rd, FRegister rs1, FRegister rs2)
void or_(Register rd, Register rs1, Register rs2)
void jalr(Register rs1, intptr_t offset=0)
void fnmsubd(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void fmsubd(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void fsd(FRegister rs2, Address addr)
void adduw(Register rd, Register rs1, Register rs2)
void fadds(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void csrrs(Register rd, uint32_t csr, Register rs1)
void ctz(Register rd, Register rs)
void EmitCJump(Label *label, COpcode op)
void sh(Register rs2, Address addr)
void EmitJump(Register rd, Label *label, Opcode op, JumpDistance distance)
void binvi(Register rd, Register rs1, intx_t shamt)
void lw(Register rd, Address addr, std::memory_order order)
void fmind(FRegister rd, FRegister rs1, FRegister rs2)
void bltz(Register rs, Label *label, JumpDistance distance=kFarJump)
void sub(Register rd, Register rs1, Register rs2)
void sltiu(Register rd, Register rs1, intptr_t imm)
void EmitSType(intptr_t imm, FRegister rs2, Register rs1, Funct3 funct3, Opcode opcode)
void fsgnjs(FRegister rd, FRegister rs1, FRegister rs2)
void EmitRType(Funct7 funct7, FRegister rs2, FRegister rs1, Funct3 funct3, FRegister rd, Opcode opcode)
void Write32(intptr_t position, uint32_t instruction)
void EmitRType(Funct5 funct5, std::memory_order order, Register rs2, Register rs1, Funct3 funct3, Register rd, Opcode opcode)
void fsgnjnd(FRegister rd, FRegister rs1, FRegister rs2)
void fcvtsw(FRegister rd, Register rs1, RoundingMode rounding=RNE)
intptr_t UpdateFarOffset(intptr_t branch_position, intptr_t new_offset)
void fcvtwud(Register rd, FRegister rs1, RoundingMode rounding=RNE)
void sll(Register rd, Register rs1, Register rs2)
void minu(Register rd, Register rs1, Register rs2)
void fcvtwd(Register rd, FRegister rs1, RoundingMode rounding=RNE)
void ror(Register rd, Register rs1, Register rs2)
void bgt(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void beqz(Register rs, Label *label, JumpDistance distance=kFarJump)
void sh3adduw(Register rd, Register rs1, Register rs2)
void xor_(Register rd, Register rs1, Register rs2)
void csrrw(Register rd, uint32_t csr, Register rs1)
void amoandw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
intptr_t UpdateJOffset(intptr_t branch_position, intptr_t new_offset)
void fmuls(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void bltu(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void bgtu(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void rolw(Register rd, Register rs1, Register rs2)
void sb(Register rs2, Address addr, std::memory_order order)
void fdivs(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void csrwi(uint32_t csr, uint32_t imm)
void EmitRType(Funct7 funct7, FRegister rs2, FRegister rs1, RoundingMode round, FRegister rd, Opcode opcode)
void ble(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void fmvxw(Register rd, FRegister rs1)
void lh(Register rd, Address addr)
void lui_fixed(Register rd, intptr_t imm)
void lh(Register rd, Address addr, std::memory_order order)
void remu(Register rd, Register rs1, Register rs2)
void fmaddd(FRegister rd, FRegister rs1, FRegister rs2, FRegister rs3, RoundingMode rounding=RNE)
void lw(Register rd, Address addr)
void EmitBranch(Register rs1, Register rs2, Label *label, Funct3 func, JumpDistance distance)
void ori(Register rd, Register rs1, intptr_t imm)
void fcvtds(FRegister rd, FRegister rs1, RoundingMode rounding=RNE)
void neg(Register rd, Register rs)
void j(Label *label, JumpDistance d=kFarJump)
void fgtd(Register rd, FRegister rs1, FRegister rs2)
void amominw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void fges(Register rd, FRegister rs1, FRegister rs2)
void bclri(Register rd, Register rs1, intx_t shamt)
void addi(Register rd, Register rs1, intptr_t imm)
void fcvtswu(FRegister rd, Register rs1, RoundingMode rounding=RNE)
void sh1add(Register rd, Register rs1, Register rs2)
void EmitR4Type(FRegister rs3, Funct2 funct2, FRegister rs2, FRegister rs1, RoundingMode round, FRegister rd, Opcode opcode)
void srli(Register rd, Register rs1, intptr_t shamt)
void fmins(FRegister rd, FRegister rs1, FRegister rs2)
void amoswapw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void sextb(Register rd, Register rs)
void xori(Register rd, Register rs1, intptr_t imm)
void bnez(Register rs, Label *label, JumpDistance distance=kFarJump)
intptr_t UpdateBOffset(intptr_t branch_position, intptr_t new_offset)
void bgeu(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void zexth(Register rd, Register rs)
void amomaxuw(Register rd, Register rs2, Address addr, std::memory_order order=std::memory_order_relaxed)
void fsqrts(FRegister rd, FRegister rs1, RoundingMode rounding=RNE)
void fmvd(FRegister rd, FRegister rs)
void srai(Register rd, Register rs1, intptr_t shamt)
void fles(Register rd, FRegister rs1, FRegister rs2)
void bge(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void min(Register rd, Register rs1, Register rs2)
void lrw(Register rd, Address addr, std::memory_order order=std::memory_order_relaxed)
void EmitCBranch(Register rs1p, Label *label, COpcode op)
void fsubs(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void add(Register rd, Register rs1, Register rs2)
void Write16(intptr_t position, uint16_t instruction)
void fmaxd(FRegister rd, FRegister rs1, FRegister rs2)
void sra(Register rd, Register rs1, Register rs2)
void bgez(Register rs, Label *label, JumpDistance distance=kFarJump)
void rol(Register rd, Register rs1, Register rs2)
void EmitRType(Funct7 funct7, intptr_t shamt, Register rs1, Funct3 funct3, Register rd, Opcode opcode)
void sexth(Register rd, Register rs)
MicroAssembler(ObjectPoolBuilder *object_pool_builder, intptr_t far_branch_level, ExtensionSet extensions)
void clmul(Register rd, Register rs1, Register rs2)
void cpop(Register rd, Register rs)
void EmitSType(intptr_t imm, Register rs2, Register rs1, Funct3 funct3, Opcode opcode)
void fclasss(Register rd, FRegister rs1)
void fence(HartEffects predecessor, HartEffects successor)
void EmitIType(intptr_t imm, Register rs1, Funct3 funct3, Register rd, Opcode opcode)
void faddd(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void fmuld(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void subi(Register rd, Register rs1, intptr_t imm)
void cpopw(Register rd, Register rs)
void and_(Register rd, Register rs1, Register rs2)
void fsgnjxd(FRegister rd, FRegister rs1, FRegister rs2)
void beq(Register rs1, Register rs2, Label *l, JumpDistance d=kFarJump)
void sh2add(Register rd, Register rs1, Register rs2)
void rem(Register rd, Register rs1, Register rs2)
void max(Register rd, Register rs1, Register rs2)
void slli(Register rd, Register rs1, intptr_t shamt)
void fsqrtd(FRegister rd, FRegister rs1, RoundingMode rounding=RNE)
void clzw(Register rd, Register rs)
void slti(Register rd, Register rs1, intptr_t imm)
void andi(Register rd, Register rs1, intptr_t imm)
void slt(Register rd, Register rs1, Register rs2)
void divu(Register rd, Register rs1, Register rs2)
void csrrwi(Register rd, uint32_t csr, uint32_t imm)
void fdivd(FRegister rd, FRegister rs1, FRegister rs2, RoundingMode rounding=RNE)
void fltd(Register rd, FRegister rs1, FRegister rs2)
void EmitJType(intptr_t imm, Register rd, Opcode opcode)
void fcvtsd(FRegister rd, FRegister rs1, RoundingMode rounding=RNE)
void sh(Register rs2, Address addr, std::memory_order order)
void EmitIType(intptr_t imm, Register rs1, Funct3 funct3, FRegister rd, Opcode opcode)
void EmitUType(intptr_t imm, Register rd, Opcode opcode)
void orn(Register rd, Register rs1, Register rs2)
void fld(FRegister rd, Address addr)
void fmvs(FRegister rd, FRegister rs)
Register index() const
static word DataOffsetFor(intptr_t cid)
Definition: runtime_api.cc:555
#define UNIMPLEMENTED
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
VkInstance instance
Definition: main.cc:48
uint8_t value
GAsyncResult * result
uint32_t * target
Dart_NativeFunction function
Definition: fuchsia.cc:51
int argument_count
Definition: fuchsia.cc:52
word ToRawSmi(const dart::Object &a)
Definition: runtime_api.cc:960
static constexpr intptr_t kWordSize
Definition: runtime_api.h:274
bool IsSmi(int64_t v)
Definition: runtime_api.cc:31
bool IsSameObject(const Object &a, const Object &b)
Definition: runtime_api.cc:60
const Object & NullObject()
Definition: runtime_api.cc:149
constexpr OperandSize kWordBytes
Definition: dart_vm.cc:33
static constexpr intptr_t kAllocationCanary
Definition: globals.h:181
const Register NULL_REG
@ kNoRegister
Definition: constants_arm.h:99
const Register TMP
const intptr_t cid
const Register PP
@ kSmiTagSize
@ kHeapObjectTag
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
dest
Definition: zip.py:79
int32_t width
const Scalar scale
SeparatedVector2 offset