Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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:
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_; }
80 void set_far_branch_level(intptr_t level) { far_branch_level_ = 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
117 void lb(Register rd, Address addr);
118 void lh(Register rd, Address addr);
119 void lw(Register rd, Address addr);
120 void lbu(Register rd, Address addr);
121 void lhu(Register rd, Address addr);
122
123 void sb(Register rs2, Address addr);
124 void sh(Register rs2, Address addr);
125 void sw(Register rs2, Address addr);
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
182 void beqz(Register rs, Label* label, JumpDistance distance = kFarJump) {
183 beq(rs, ZR, label, distance);
184 }
185 void bnez(Register rs, Label* label, JumpDistance distance = kFarJump) {
186 bne(rs, ZR, label, distance);
187 }
188 void blez(Register rs, Label* label, JumpDistance distance = kFarJump) {
189 bge(ZR, rs, label, distance);
190 }
191 void bgez(Register rs, Label* label, JumpDistance distance = kFarJump) {
192 bge(rs, ZR, label, distance);
193 }
194 void bltz(Register rs, Label* label, JumpDistance distance = kFarJump) {
195 blt(rs, ZR, label, distance);
196 }
197 void bgtz(Register rs, Label* label, JumpDistance distance = kFarJump) {
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,
256 Address addr,
257 std::memory_order order = std::memory_order_relaxed);
258 void scw(Register rd,
259 Register rs2,
260 Address addr,
261 std::memory_order order = std::memory_order_relaxed);
263 Register rs2,
264 Address addr,
265 std::memory_order order = std::memory_order_relaxed);
267 Register rs2,
268 Address addr,
269 std::memory_order order = std::memory_order_relaxed);
271 Register rs2,
272 Address addr,
273 std::memory_order order = std::memory_order_relaxed);
275 Register rs2,
276 Address addr,
277 std::memory_order order = std::memory_order_relaxed);
279 Register rs2,
280 Address addr,
281 std::memory_order order = std::memory_order_relaxed);
283 Register rs2,
284 Address addr,
285 std::memory_order order = std::memory_order_relaxed);
287 Register rs2,
288 Address addr,
289 std::memory_order order = std::memory_order_relaxed);
291 Register rs2,
292 Address addr,
293 std::memory_order order = std::memory_order_relaxed);
295 Register rs2,
296 Address addr,
297 std::memory_order order = std::memory_order_relaxed);
298
299 // ==== RV64A ====
300#if XLEN >= 64
301 void lrd(Register rd,
302 Address addr,
303 std::memory_order order = std::memory_order_relaxed);
304 void scd(Register rd,
305 Register rs2,
306 Address addr,
307 std::memory_order order = std::memory_order_relaxed);
308 void amoswapd(Register rd,
309 Register rs2,
310 Address addr,
311 std::memory_order order = std::memory_order_relaxed);
312 void amoaddd(Register rd,
313 Register rs2,
314 Address addr,
315 std::memory_order order = std::memory_order_relaxed);
316 void amoxord(Register rd,
317 Register rs2,
318 Address addr,
319 std::memory_order order = std::memory_order_relaxed);
320 void amoandd(Register rd,
321 Register rs2,
322 Address addr,
323 std::memory_order order = std::memory_order_relaxed);
324 void amoord(Register rd,
325 Register rs2,
326 Address addr,
327 std::memory_order order = std::memory_order_relaxed);
328 void amomind(Register rd,
329 Register rs2,
330 Address addr,
331 std::memory_order order = std::memory_order_relaxed);
332 void amomaxd(Register rd,
333 Register rs2,
334 Address addr,
335 std::memory_order order = std::memory_order_relaxed);
336 void amominud(Register rd,
337 Register rs2,
338 Address addr,
339 std::memory_order order = std::memory_order_relaxed);
340 void amomaxud(Register rd,
341 Register rs2,
342 Address addr,
343 std::memory_order order = std::memory_order_relaxed);
344#endif // XLEN >= 64
345
346#if XLEN == 32
347 void lr(Register rd,
348 Address addr,
349 std::memory_order order = std::memory_order_relaxed) {
350 lrw(rd, addr, order);
351 }
352 void sc(Register rd,
353 Register rs2,
354 Address addr,
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 ====
385 void flw(FRegister rd, Address addr);
386 void fsw(FRegister rs2, Address addr);
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 ====
470 void fld(FRegister rd, Address addr);
471 void fsd(FRegister rs2, Address addr);
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 // ==== Dart Simulator Debugging ====
608
609 private:
610 // ==== RV32/64C ====
611 void c_lwsp(Register rd, Address addr);
612#if XLEN == 32
613 void c_flwsp(FRegister rd, Address addr);
614#else
615 void c_ldsp(Register rd, Address addr);
616#endif
617 void c_fldsp(FRegister rd, Address addr);
618
619 void c_swsp(Register rs2, Address addr);
620#if XLEN == 32
621 void c_fswsp(FRegister rs2, Address addr);
622#else
623 void c_sdsp(Register rs2, Address addr);
624#endif
625 void c_fsdsp(FRegister rs2, Address addr);
626
627 void c_lw(Register rd, Address addr);
628 void c_ld(Register rd, Address addr);
629 void c_flw(FRegister rd, Address addr);
630 void c_fld(FRegister rd, Address addr);
631
632 void c_sw(Register rs2, Address addr);
633 void c_sd(Register rs2, Address addr);
634 void c_fsw(FRegister rs2, Address addr);
635 void c_fsd(FRegister rs2, Address addr);
636
637 void c_j(Label* label);
638#if XLEN == 32
639 void c_jal(Label* label);
640#endif
641 void c_jr(Register rs1);
642 void c_jalr(Register rs1);
643
644 void c_beqz(Register rs1p, Label* label);
645 void c_bnez(Register rs1p, Label* label);
646
647 void c_li(Register rd, intptr_t imm);
648 void c_lui(Register rd, uintptr_t imm);
649
650 void c_addi(Register rd, Register rs1, intptr_t imm);
651#if XLEN >= 64
652 void c_addiw(Register rd, Register rs1, intptr_t imm);
653#endif
654 void c_addi16sp(Register rd, Register rs1, intptr_t imm);
655 void c_addi4spn(Register rdp, Register rs1, intptr_t imm);
656
657 void c_slli(Register rd, Register rs1, intptr_t imm);
658 void c_srli(Register rd, Register rs1, intptr_t imm);
659 void c_srai(Register rd, Register rs1, intptr_t imm);
660 void c_andi(Register rd, Register rs1, intptr_t imm);
661
662 void c_mv(Register rd, Register rs2);
663
664 void c_add(Register rd, Register rs1, Register rs2);
665 void c_and(Register rd, Register rs1, Register rs2);
666 void c_or(Register rd, Register rs1, Register rs2);
667 void c_xor(Register rd, Register rs1, Register rs2);
668 void c_sub(Register rd, Register rs1, Register rs2);
669#if XLEN >= 64
670 void c_addw(Register rd, Register rs1, Register rs2);
671 void c_subw(Register rd, Register rs1, Register rs2);
672#endif
673
674 void c_nop();
675 void c_ebreak();
676
677 protected:
678 intptr_t UpdateCBOffset(intptr_t branch_position, intptr_t new_offset);
679 intptr_t UpdateCJOffset(intptr_t branch_position, intptr_t new_offset);
680 intptr_t UpdateBOffset(intptr_t branch_position, intptr_t new_offset);
681 intptr_t UpdateJOffset(intptr_t branch_position, intptr_t new_offset);
682 intptr_t UpdateFarOffset(intptr_t branch_position, intptr_t new_offset);
683
684 intptr_t Position() { return buffer_.Size(); }
686 Register rs2,
687 Label* label,
688 Funct3 func,
689 JumpDistance distance);
690 void EmitJump(Register rd, Label* label, Opcode op, JumpDistance distance);
691 void EmitCBranch(Register rs1p, Label* label, COpcode op);
692 void EmitCJump(Label* label, COpcode op);
693
694 void EmitRType(Funct5 funct5,
695 std::memory_order order,
696 Register rs2,
697 Register rs1,
698 Funct3 funct3,
699 Register rd,
700 Opcode opcode);
701 void EmitRType(Funct7 funct7,
702 Register rs2,
703 Register rs1,
704 Funct3 funct3,
705 Register rd,
706 Opcode opcode);
707 void EmitRType(Funct7 funct7,
708 FRegister rs2,
709 FRegister rs1,
710 Funct3 funct3,
711 FRegister rd,
712 Opcode opcode);
713 void EmitRType(Funct7 funct7,
714 FRegister rs2,
715 FRegister rs1,
717 FRegister rd,
718 Opcode opcode);
719 void EmitRType(Funct7 funct7,
720 FRegister rs2,
721 Register rs1,
723 FRegister rd,
724 Opcode opcode);
725 void EmitRType(Funct7 funct7,
726 FRegister rs2,
727 Register rs1,
728 Funct3 funct3,
729 FRegister rd,
730 Opcode opcode);
731 void EmitRType(Funct7 funct7,
732 FRegister rs2,
733 FRegister rs1,
734 Funct3 funct3,
735 Register rd,
736 Opcode opcode);
737 void EmitRType(Funct7 funct7,
738 FRegister rs2,
739 FRegister rs1,
741 Register rd,
742 Opcode opcode);
743 void EmitRType(Funct7 funct7,
744 intptr_t shamt,
745 Register rs1,
746 Funct3 funct3,
747 Register rd,
748 Opcode opcode);
749
751 Funct2 funct2,
752 FRegister rs2,
753 FRegister rs1,
755 FRegister rd,
756 Opcode opcode);
757
758 void EmitIType(intptr_t imm,
759 Register rs1,
760 Funct3 funct3,
761 Register rd,
762 Opcode opcode);
763 void EmitIType(intptr_t imm,
764 Register rs1,
765 Funct3 funct3,
766 FRegister rd,
767 Opcode opcode);
768
769 void EmitSType(intptr_t imm,
770 Register rs2,
771 Register rs1,
772 Funct3 funct3,
773 Opcode opcode);
774 void EmitSType(intptr_t imm,
775 FRegister rs2,
776 Register rs1,
777 Funct3 funct3,
778 Opcode opcode);
779
780 void EmitBType(intptr_t imm,
781 Register rs2,
782 Register rs1,
783 Funct3 funct3,
784 Opcode opcode);
785
786 void EmitUType(intptr_t imm, Register rd, Opcode opcode);
787
788 void EmitJType(intptr_t imm, Register rd, Opcode opcode);
789
790 uint16_t Read16(intptr_t position) {
791 return buffer_.Load<uint16_t>(position);
792 }
793 void Write16(intptr_t position, uint16_t instruction) {
794 return buffer_.Store<uint16_t>(position, instruction);
795 }
796 void Emit16(uint16_t instruction) {
798 buffer_.Emit<uint16_t>(instruction);
799 }
800 uint32_t Read32(intptr_t position) {
801 return buffer_.Load<uint32_t>(position);
802 }
803 void Write32(intptr_t position, uint32_t instruction) {
804 return buffer_.Store<uint32_t>(position, instruction);
805 }
806
807 public:
808 void Emit32(uint32_t instruction) {
810 buffer_.Emit<uint32_t>(instruction);
811 }
812 void Emit64(uint64_t instruction) {
814 buffer_.Emit<uint64_t>(instruction);
815 }
816
817 protected:
818 ExtensionSet extensions_;
820};
821
822class Assembler : public MicroAssembler {
823 public:
825 intptr_t far_branch_level = 0);
827
830
833
834 void PushRegisters(const RegisterSet& registers);
835 void PopRegisters(const RegisterSet& registers);
836
837 void PushRegistersInOrder(std::initializer_list<Register> regs);
838
840
841 // Push all registers which are callee-saved according to the ARM64 ABI.
843
844 // Pop all registers which are callee-saved according to the ARM64 ABI.
846
847 void ExtendValue(Register rd, Register rn, OperandSize sz) override;
849 Register rn,
850 OperandSize sz = kWordBytes) override;
851
852 void Drop(intptr_t stack_elements) {
853 ASSERT(stack_elements >= 0);
854 if (stack_elements > 0) {
855 AddImmediate(SP, SP, stack_elements * target::kWordSize);
856 }
857 }
858
859 void Bind(Label* label) override { MicroAssembler::Bind(label); }
860 // Unconditional jump to a given label.
861 void Jump(Label* label, JumpDistance distance = kFarJump) {
862 j(label, distance);
863 }
864 // Unconditional jump to a given address in register.
865 void Jump(Register target) { jr(target); }
866 // Unconditional jump to a given address in memory. Clobbers TMP.
867 void Jump(const Address& address);
868
875
876#if defined(TARGET_USES_THREAD_SANITIZER)
877 void TsanLoadAcquire(Register addr);
878 void TsanStoreRelease(Register addr);
879#endif
880
882 const Address& address,
883 OperandSize size = kWordBytes) override;
884
886 const Address& address,
887 OperandSize size = kWordBytes) override;
888
890 Address address,
891 OperandSize size = kWordBytes) override;
892
893 // Debugging and bringup support.
894 void Breakpoint() override { trap(); }
895
897 if (prologue_offset_ == -1) {
899 }
900 }
901
902 void ReserveAlignedFrameSpace(intptr_t frame_space);
903
904 // In debug mode, this generates code to check that:
905 // FP + kExitLinkSlotFromEntryFp == SP
906 // or triggers breakpoint otherwise.
908
909 // Instruction pattern from entrypoint is used in Dart frame prologs
910 // to set up the frame and save a PC which can be used to figure out the
911 // RawInstruction object corresponding to the code running in the frame.
912 static constexpr intptr_t kEntryPointToPcMarkerOffset = 0;
913 static intptr_t EntryPointToPcMarkerOffset() {
915 }
916
917 // On some other platforms, we draw a distinction between safe and unsafe
918 // smis.
919 static bool IsSafe(const Object& object) { return true; }
920 static bool IsSafeSmi(const Object& object) { return target::IsSmi(object); }
921
925
926 // Branches to the given label if the condition holds.
927 void BranchIf(Condition condition,
928 Label* label,
929 JumpDistance distance = kFarJump);
931 Label* label,
932 JumpDistance distance = kFarJump);
934 intptr_t bit_number,
935 Condition condition,
936 Label* label,
937 JumpDistance distance = kFarJump);
938 void SetIf(Condition condition, Register rd);
939
940 void SmiUntag(Register reg) { SmiUntag(reg, reg); }
941 void SmiUntag(Register dst, Register src) { srai(dst, src, kSmiTagSize); }
942 void SmiTag(Register reg) override { SmiTag(reg, reg); }
943 void SmiTag(Register dst, Register src) { slli(dst, src, kSmiTagSize); }
944
945 // Truncates upper bits.
947 if (result == value) {
948 ASSERT(TMP != value);
950 value = TMP;
951 }
952 ASSERT(value != result);
956 LoadFieldFromOffset(result, value, target::Mint::value_offset(),
958 Bind(&done);
959 }
960
961#if XLEN != 32
963 if (result == value) {
964 ASSERT(TMP != value);
966 value = TMP;
967 }
968 ASSERT(value != result);
972 LoadFieldFromOffset(result, value, target::Mint::value_offset());
973 Bind(&done);
974 }
975#endif
976
978 Label* label,
979 JumpDistance distance = kFarJump);
981 Label* label,
982 JumpDistance distance = kFarJump) override;
983
984 void ArithmeticShiftRightImmediate(Register reg, intptr_t shift) override;
986 Register reg2,
987 intptr_t offset,
989 Register temp,
990 Label* equals) override;
991
992 void JumpAndLink(const Code& code,
998
1000 const Code& code,
1005 snapshot_behavior);
1006 }
1007
1008 // Emit a call that shares its object pool entries with other calls
1009 // that have the same equivalence marker.
1011 const Code& code,
1012 const Object& equivalence,
1014
1015 void Call(Address target);
1016 void Call(Register target);
1017 void Call(const Code& code) { JumpAndLink(code); }
1018
1021
1022 void AddImmediate(Register dest, intx_t imm) {
1023 AddImmediate(dest, dest, imm);
1024 }
1026 intx_t imm,
1027 OperandSize width = kWordBytes) override {
1028 MulImmediate(dest, dest, imm, width);
1029 }
1030 void AddRegisters(Register dest, Register src) { add(dest, dest, src); }
1031 // [dest] = [src] << [scale] + [value].
1033 Register src,
1035 int32_t value) {
1036 if (scale == 0) {
1037 AddImmediate(dest, src, value);
1038 } else {
1039 slli(dest, src, scale);
1040 AddImmediate(dest, dest, value);
1041 }
1042 }
1043 void AddShifted(Register dest, Register base, Register index, intx_t shift);
1044 void SubRegisters(Register dest, Register src) { sub(dest, dest, src); }
1045
1046 // Macros accepting a pp Register argument may attempt to load values from
1047 // the object pool when possible. Unless you are sure that the untagged object
1048 // pool pointer is in another register, or that it is not available at all,
1049 // PP should be passed for pp. `dest` can be TMP2, `rn` cannot. `dest` can be
1050 // TMP.
1052 Register rn,
1053 intx_t imm,
1054 OperandSize sz = kWordBytes);
1056 Register rn,
1057 intx_t imm,
1060 Register rn,
1061 intx_t imm,
1062 OperandSize sz = kWordBytes);
1063 void AndImmediate(Register rd, intx_t imm) override {
1064 AndImmediate(rd, rd, imm);
1065 }
1067 Register src1,
1068 Register src2 = kNoRegister) override {
1069 ASSERT(src1 != src2); // Likely a mistake.
1070 if (src2 == kNoRegister) {
1071 src2 = dst;
1072 }
1073 and_(dst, src2, src1);
1074 }
1076 Register rn,
1077 intx_t imm,
1078 OperandSize sz = kWordBytes);
1079 void OrImmediate(Register rd, intx_t imm) { OrImmediate(rd, rd, imm); }
1081 Register rn,
1082 intx_t imm,
1083 OperandSize sz = kWordBytes);
1084 void LslImmediate(Register rd, int32_t shift) { slli(rd, rd, shift); }
1085 void LslRegister(Register dst, Register shift) override {
1086 sll(dst, dst, shift);
1087 }
1088 void LsrImmediate(Register rd, int32_t shift) override {
1089 srli(rd, rd, shift);
1090 }
1091 void TestImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
1093 intx_t imm,
1094 OperandSize sz = kWordBytes) override;
1095
1097 void Load(Register dest,
1098 const Address& address,
1099 OperandSize sz = kWordBytes) override;
1100 // For loading indexed payloads out of tagged objects like Arrays. If the
1101 // payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
1102 // [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
1104 Register base,
1105 int32_t payload_offset,
1106 Register index,
1108 OperandSize sz = kWordBytes) override;
1117
1118 void LoadFromStack(Register dst, intptr_t depth);
1119 void StoreToStack(Register src, intptr_t depth);
1120 void CompareToStack(Register src, intptr_t depth);
1121
1122 void Store(Register src,
1123 const Address& address,
1124 OperandSize sz = kWordBytes) override;
1125 void StoreZero(const Address& address, Register temp = kNoRegister) {
1126 Store(ZR, address);
1127 }
1136
1139 }
1141 StoreDToOffset(src, base, offset);
1142 }
1143 void MoveUnboxedDouble(FpuRegister dst, FpuRegister src) { fmvd(dst, src); }
1144
1146 // No single register SIMD on RISC-V.
1147 UNREACHABLE();
1148 }
1150 // No single register SIMD on RISC-V.
1151 UNREACHABLE();
1152 }
1154 // No single register SIMD on RISC-V.
1155 UNREACHABLE();
1156 }
1157
1159 Register value,
1160 CanBeSmi can_value_be_smi,
1161 Register scratch) override;
1163 Register slot,
1164 Register value,
1165 CanBeSmi can_value_be_smi,
1166 Register scratch) override;
1168
1170 Register object,
1171 const Address& dest,
1172 const Object& value,
1173 MemoryOrder memory_order = kRelaxedNonAtomic,
1174 OperandSize size = kWordBytes) override;
1175
1176 // Stores a non-tagged value into a heap object.
1178 const Address& dest,
1179 Register value);
1180
1181 // Object pool, loading from pool, etc.
1183
1184 bool constant_pool_allowed() const { return constant_pool_allowed_; }
1185 void set_constant_pool_allowed(bool b) { constant_pool_allowed_ = b; }
1186
1187 bool CanLoadFromObjectPool(const Object& object) const;
1189 const ExternalLabel* label,
1193
1194 // Note: the function never clobbers TMP, TMP2 scratch registers.
1195 void LoadObject(Register dst, const Object& obj) {
1196 LoadObjectHelper(dst, obj, false);
1197 }
1198 // Note: the function never clobbers TMP, TMP2 scratch registers.
1200 Register dst,
1201 const Object& obj,
1204 LoadObjectHelper(dst, obj, true, snapshot_behavior);
1205 }
1206 // Note: the function never clobbers TMP, TMP2 scratch registers.
1207 void LoadImmediate(Register reg, intx_t imm) override;
1208
1209 void LoadSImmediate(FRegister reg, float imms);
1210 void LoadDImmediate(FRegister reg, double immd);
1212
1213 // Load word from pool from the given offset using encoding that
1214 // InstructionPattern::DecodeLoadWordFromPool can decode.
1215 //
1216 // Note: the function never clobbers TMP, TMP2 scratch registers.
1217 void LoadWordFromPoolIndex(Register dst, intptr_t index, Register pp = PP);
1218
1219 // Store word to pool at the given offset.
1220 //
1221 // Note: clobbers TMP, does not clobber TMP2.
1222 void StoreWordToPoolIndex(Register src, intptr_t index, Register pp = PP);
1223
1224 void PushObject(const Object& object) {
1225 if (IsSameObject(compiler::NullObject(), object)) {
1227 } else if (target::IsSmi(object) && (target::ToRawSmi(object) == 0)) {
1229 } else {
1230 LoadObject(TMP, object);
1232 }
1233 }
1234 void PushImmediate(int64_t immediate) {
1235 if (immediate == 0) {
1237 } else {
1238 LoadImmediate(TMP, immediate);
1240 }
1241 }
1242 void CompareObject(Register reg, const Object& object);
1243
1246
1248 Register temp,
1249 intptr_t low,
1250 intptr_t high,
1251 RangeCheckCondition condition,
1252 Label* target) override;
1253
1257 intptr_t class_id,
1258 Register scratch = kNoRegister);
1259 // Note: input and output registers must be different.
1263 Register src,
1264 Register scratch,
1265 bool can_be_null = false) override;
1266
1267 void EnterFrame(intptr_t frame_size);
1269 void Ret() { ret(); }
1270
1271 // Sets the return address to [value] as if there was a call.
1272 // On RISC-V sets RA.
1274
1275 // Emit code to transition between generated mode and native mode.
1276 //
1277 // These require and ensure that CSP and SP are equal and aligned and require
1278 // a scratch register (in addition to TMP/TMP2).
1279
1280 void TransitionGeneratedToNative(Register destination_address,
1281 Register new_exit_frame,
1282 Register new_exit_through_ffi,
1283 bool enter_safepoint);
1285 bool exit_safepoint,
1286 bool ignore_unwind_in_progress = false);
1288 void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress);
1289
1290 void CheckFpSpDist(intptr_t fp_sp_dist);
1291
1295
1296 // Restores the values of the registers that are blocked to cache some values
1297 // e.g. WRITE_BARRIER_STATE and NULL_REG.
1299
1301
1302 void EnterDartFrame(intptr_t frame_size, Register new_pp = kNoRegister);
1303 void EnterOsrFrame(intptr_t extra_size, Register new_pp = kNoRegister);
1305 void LeaveDartFrame(intptr_t fp_sp_dist);
1306
1307 // For non-leaf runtime calls. For leaf runtime calls, use LeafRuntimeScope,
1308 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
1309
1310 // Set up a stub frame so that the stack traversal code can easily identify
1311 // a stub frame.
1314
1315 // Set up a frame for calling a C function.
1316 // Automatically save the pinned registers in Dart which are not callee-
1317 // saved in the native calling convention.
1318 // Use together with CallCFunction.
1319 void EnterCFrame(intptr_t frame_space);
1321
1325
1326 void CombineHashes(Register dst, Register other) override;
1327 void FinalizeHashForSize(intptr_t bit_size,
1328 Register dst,
1329 Register scratch = TMP) override;
1330
1331 // If allocation tracing for |cid| is enabled, will jump to |trace| label,
1332 // which will allocate in the runtime where tracing occurs.
1334 Label* trace,
1335 Register temp_reg,
1337
1339 Label* trace,
1340 Register temp_reg,
1342
1343 void TryAllocateObject(intptr_t cid,
1344 intptr_t instance_size,
1345 Label* failure,
1346 JumpDistance distance,
1347 Register instance_reg,
1348 Register temp_reg) override;
1349
1350 void TryAllocateArray(intptr_t cid,
1351 intptr_t instance_size,
1352 Label* failure,
1354 Register end_address,
1355 Register temp1,
1356 Register temp2);
1357
1359#if defined(DEBUG)
1360 Label okay;
1361 lx(tmp, Address(top, 0));
1362 subi(tmp, tmp, kAllocationCanary);
1363 beqz(tmp, &okay, Assembler::kNearJump);
1364 Stop("Allocation canary");
1365 Bind(&okay);
1366#endif
1367 }
1369#if defined(DEBUG)
1370 ASSERT(top != TMP);
1372 sx(TMP, Address(top, 0));
1373#endif
1374 }
1375
1376 // Copy [size] bytes from [src] address to [dst] address.
1377 // [size] should be a multiple of word size.
1378 // Clobbers [src], [dst], [size] and [temp] registers.
1380 Register dst,
1381 Register size,
1382 Register temp);
1383
1384 // This emits an PC-relative call of the form "bl <offset>". The offset
1385 // is not yet known and needs therefore relocation to the right place before
1386 // the code can be used.
1387 //
1388 // The necessary information for the "linker" (i.e. the relocation
1389 // information) is stored in [UntaggedCode::static_calls_target_table_]: an
1390 // entry of the form
1391 //
1392 // (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
1393 //
1394 // will be used during relocation to fix the offset.
1395 //
1396 // The provided [offset_into_target] will be added to calculate the final
1397 // destination. It can be used e.g. for calling into the middle of a
1398 // function.
1399 void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
1400
1401 // This emits an PC-relative tail call of the form "b <offset>".
1402 //
1403 // See also above for the pc-relative call.
1404 void GenerateUnRelocatedPcRelativeTailCall(intptr_t offset_into_target = 0);
1405
1406 static bool AddressCanHoldConstantIndex(const Object& constant,
1407 bool is_external,
1408 intptr_t cid,
1409 intptr_t index_scale);
1410
1412 intptr_t cid,
1413 intptr_t index_scale,
1414 Register array,
1415 intptr_t index) const;
1417 bool is_external,
1418 intptr_t cid,
1419 intptr_t index_scale,
1420 Register array,
1421 intptr_t index);
1423 intptr_t cid,
1424 intptr_t index_scale,
1425 bool index_unboxed,
1426 Register array,
1427 Register index,
1428 Register temp);
1429
1431 bool is_external,
1432 intptr_t cid,
1433 intptr_t index_scale,
1434 bool index_unboxed,
1435 Register array,
1436 Register index);
1437
1439 Register field,
1440 Register scratch);
1441
1444 Register offset_in_words_as_smi) override;
1445
1448 int32_t offset) override {
1450 }
1451
1452 // Returns object data offset for address calculation; for heap objects also
1453 // accounts for the tag.
1454 static int32_t HeapDataOffset(bool is_external, intptr_t cid) {
1455 return is_external
1456 ? 0
1457 : (target::Instance::DataOffsetFor(cid) - kHeapObjectTag);
1458 }
1459
1461 Register rs1,
1462 intx_t imm,
1463 Label* overflow);
1465 Register rs1,
1466 intx_t imm,
1467 Label* overflow);
1469 Register rs1,
1470 intx_t imm,
1471 Label* overflow);
1473 Register rs1,
1474 Register rs2,
1475 Label* overflow);
1477 Register rs1,
1478 Register rs2,
1479 Label* overflow);
1481 Register rs1,
1482 Register rs2,
1483 Label* overflow);
1484
1485 // Clobbers [rs].
1487
1488 private:
1489 bool constant_pool_allowed_;
1490
1491 enum DeferredCompareType {
1492 kNone,
1493 kCompareReg,
1494 kCompareImm,
1495 kTestReg,
1496 kTestImm,
1497 };
1498 DeferredCompareType deferred_compare_ = kNone;
1499 Register deferred_left_ = kNoRegister;
1500 Register deferred_reg_ = kNoRegister;
1501 intptr_t deferred_imm_ = 0;
1502
1503 // Note: the function never clobbers TMP, TMP2 scratch registers.
1504 void LoadObjectHelper(
1505 Register dst,
1506 const Object& obj,
1507 bool is_unique,
1510
1511 void JumpAndLink(intptr_t target_code_pool_index, CodeEntryKind entry_kind);
1512
1513 friend class dart::FlowGraphCompiler;
1514 std::function<void(Register reg)> generate_invoke_write_barrier_wrapper_;
1515 std::function<void()> generate_invoke_array_write_barrier_;
1516
1519};
1520
1521} // namespace compiler
1522} // namespace dart
1523
1524#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
static void round(SkPoint *p)
static bool equals(T *a, T *b)
#define UNREACHABLE()
Definition assert.h:248
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 TransitionNativeToGenerated(Register scratch, bool exit_safepoint, bool ignore_unwind_in_progress=false)
void LoadDFromOffset(DRegister reg, Register base, int32_t offset, Condition cond=AL)
void LoadStaticFieldAddress(Register address, Register field, Register scratch)
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 Store(Register src, const Address &address, OperandSize sz=kWordBytes) override
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 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 AddScaled(Register dest, Register src, ScaleFactor scale, int32_t value)
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)
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 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 rev8(Register rd, Register rs)
void sltz(Register rd, Register rs)
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 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 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 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 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
#define UNIMPLEMENTED
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
VkInstance instance
Definition main.cc:48
static bool b
uint8_t value
GAsyncResult * result
uint32_t * target
int argument_count
Definition fuchsia.cc:52
word ToRawSmi(const dart::Object &a)
bool IsSmi(int64_t v)
bool IsSameObject(const Object &a, const Object &b)
const Object & NullObject()
constexpr OperandSize kWordBytes
static constexpr intptr_t kAllocationCanary
Definition globals.h:181
const Register NULL_REG
@ kHeapObjectTag
@ kNoRegister
const Register TMP
const intptr_t cid
const Register PP
#define DISALLOW_ALLOCATION()
Definition globals.h:604
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
int32_t width
const Scalar scale
Point offset