9#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
12#if defined(USING_SIMULATOR)
28 "Trace simulator execution after instruction count reached.");
32 "Instruction address or instruction count to stop simulator at.");
39class SimulatorSetjmpBuffer {
43 simulator_->set_last_setjmp_buffer(
this);
47 explicit SimulatorSetjmpBuffer(Simulator* sim) {
49 link_ = sim->last_setjmp_buffer();
50 sim->set_last_setjmp_buffer(
this);
51 sp_ =
static_cast<uword>(sim->get_register(
SP));
54 ~SimulatorSetjmpBuffer() {
55 ASSERT(simulator_->last_setjmp_buffer() ==
this);
56 simulator_->set_last_setjmp_buffer(link_);
59 SimulatorSetjmpBuffer*
link() {
return link_; }
61 uword sp() {
return sp_; }
65 Simulator* simulator_;
66 SimulatorSetjmpBuffer* link_;
69 friend class Simulator;
81 uword address_of_ecall_instruction() {
82 return reinterpret_cast<uword>(&ecall_instruction_);
85 uword external_function()
const {
return external_function_; }
91 static Redirection*
Get(
uword external_function,
94 MutexLocker ml(mutex_);
96 Redirection* old_head = list_.load(std::memory_order_relaxed);
97 for (Redirection* current = old_head; current !=
nullptr;
98 current = current->next_) {
99 if (current->external_function_ == external_function)
return current;
102 Redirection* redirection =
104 redirection->next_ = old_head;
109 list_.store(redirection, std::memory_order_release);
114 static Redirection* FromECallInstruction(uintx_t ecall_instruction) {
115 char* addr_of_ecall =
reinterpret_cast<char*
>(ecall_instruction);
116 char* addr_of_redirection =
117 addr_of_ecall -
OFFSET_OF(Redirection, ecall_instruction_);
118 return reinterpret_cast<Redirection*
>(addr_of_redirection);
125 static uword FunctionForRedirect(
uword address_of_ecall) {
126 for (Redirection* current = list_.load(std::memory_order_acquire);
127 current !=
nullptr; current = current->next_) {
128 if (current->address_of_ecall_instruction() == address_of_ecall) {
129 return current->external_function_;
136 Redirection(
uword external_function,
139 : external_function_(external_function),
140 call_kind_(call_kind),
142 ecall_instruction_(Instr::kSimulatorRedirectInstruction),
145 uword external_function_;
148 uint32_t ecall_instruction_;
150 static std::atomic<Redirection*> list_;
151 static Mutex* mutex_;
154std::atomic<Redirection*> Redirection::list_ = {
nullptr};
155Mutex* Redirection::mutex_ =
new Mutex();
160 Redirection* redirection =
162 return redirection->address_of_ecall_instruction();
166 return Redirection::FunctionForRedirect(redirect);
172 Simulator* simulator = isolate->simulator();
173 if (simulator ==
nullptr) {
174 NoSafepointScope no_safepoint;
176 isolate->set_simulator(simulator);
186 reserved_address_(0),
190 last_setjmp_buffer_(nullptr) {
198 new char[(OSThread::GetSpecifiedStackSize() +
199 OSThread::kStackSizeBufferMax + kSimulatorStackUnderflowSize)];
201 stack_limit_ =
reinterpret_cast<uword>(stack_);
203 overflow_stack_limit_ = stack_limit_ + OSThread::kStackSizeBufferMax;
205 stack_base_ = overflow_stack_limit_ + OSThread::GetSpecifiedStackSize();
210 xregs_[
i] = random_.NextUInt64();
217 fregs_[
i] = bit_cast<double>(kNaNBox);
222 set_xreg(
SP, stack_base());
225 set_xreg(
RA, kBadLR);
229Simulator::~Simulator() {
231 Isolate* isolate = Isolate::Current();
232 if (isolate !=
nullptr) {
233 isolate->set_simulator(
nullptr);
237void Simulator::PrepareCall(PreservedRegisters* preserved) {
240 preserved->xregs[
i] = xregs_[
i];
242 xregs_[
i] = random_.NextUInt64();
246 preserved->fregs[
i] = fregs_[
i];
252 fregs_[
i] = bit_cast<double>(kNaNBox);
258void Simulator::ClobberVolatileRegisters() {
260 reserved_address_ = reserved_value_ = 0;
263 xregs_[
i] = random_.NextUInt64();
272 fregs_[
i] = bit_cast<double>(kNaNBox);
278void Simulator::SavePreservedRegisters(PreservedRegisters* preserved) {
281 preserved->xregs[
i] = xregs_[
i];
284 preserved->fregs[
i] = fregs_[
i];
289void Simulator::CheckPreservedRegisters(PreservedRegisters* preserved) {
291 if (preserved->xregs[
SP] != xregs_[
SP]) {
294 FATAL(
"Stack unbalanced");
296 const intptr_t kPreservedAtCall =
299 if ((kPreservedAtCall & (1 <<
i)) != 0) {
300 if (preserved->xregs[
i] != xregs_[
i]) {
307 if (bit_cast<uint64_t>(preserved->fregs[
i]) !=
308 bit_cast<uint64_t>(fregs_[
i])) {
316void Simulator::RunCall(intx_t entry, PreservedRegisters* preserved) {
318 set_xreg(
RA, kEndSimulatingPC);
320 CheckPreservedRegisters(preserved);
323int64_t Simulator::Call(intx_t entry,
331 const intptr_t sp_before_call = get_xreg(
SP);
335 set_fregd(
FA0, parameter0);
336 set_fregd(
FA1, parameter1);
337 set_fregd(
FA2, parameter2);
338 set_fregd(
FA3, parameter3);
340 set_xreg(
A0, parameter0);
341 set_xreg(
A1, parameter1);
342 set_xreg(
A2, parameter2);
343 set_xreg(
A3, parameter3);
347 intptr_t stack_pointer = sp_before_call;
348 if (OS::ActivationFrameAlignment() > 1) {
350 Utils::RoundDown(stack_pointer, OS::ActivationFrameAlignment());
352 set_xreg(
SP, stack_pointer);
359 set_xreg(
RA, kEndSimulatingPC);
364 PreservedRegisters preserved;
365 SavePreservedRegisters(&preserved);
372 CheckPreservedRegisters(&preserved);
375 set_xreg(
SP, sp_before_call);
376 int64_t return_value;
378 return_value = get_fregd(
FA0);
380 return_value = get_xreg(
A0);
386 if (
LIKELY(FLAG_trace_sim_after == ULLONG_MAX)) {
393void Simulator::ExecuteNoTrace() {
394 while (pc_ != kEndSimulatingPC) {
395 uint16_t parcel = *
reinterpret_cast<uint16_t*
>(pc_);
397 CInstr instr(parcel);
400 Instr instr(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_)));
407void Simulator::ExecuteTrace() {
408 while (pc_ != kEndSimulatingPC) {
409 uint16_t parcel = *
reinterpret_cast<uint16_t*
>(pc_);
411 CInstr instr(parcel);
412 if (IsTracingExecution()) {
413 Disassembler::Disassemble(pc_, pc_ + instr.length());
417 Instr instr(
LoadUnaligned(
reinterpret_cast<uint32_t*
>(pc_)));
418 if (IsTracingExecution()) {
419 Disassembler::Disassemble(pc_, pc_ + instr.length());
427bool Simulator::IsTracingExecution()
const {
428 return instret_ > FLAG_trace_sim_after;
434 SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
435 while (buf->link() !=
nullptr && buf->link()->sp() <= sp) {
443 StackResource::Unwind(thread);
449 set_xreg(
SP,
static_cast<uintx_t
>(sp));
450 set_xreg(
FP,
static_cast<uintx_t
>(
fp));
451 set_xreg(
THR,
reinterpret_cast<uintx_t
>(thread));
452#if defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
453 set_xreg(
GP, thread->saved_shadow_call_stack());
456 thread->set_vm_tag(VMTag::kDartTagId);
458 thread->set_top_exit_frame_info(0);
462 uintx_t pp = FLAG_precompiled_mode
463 ?
static_cast<uintx_t
>(thread->global_object_pool())
464 : *
reinterpret_cast<uintx_t*
>(
470 thread->write_barrier_mask() ^
471 ((UntaggedObject::kGenerationalBarrierMask << 1) - 1));
472 set_xreg(
NULL_REG,
static_cast<uintx_t
>(Object::null()));
473 if (FLAG_precompiled_mode) {
475 reinterpret_cast<uintx_t
>(thread->dispatch_table_array()));
481void Simulator::PrintRegisters() {
494 OS::Print(
" pc: %8x\n", pc_);
496 OS::Print(
" pc: %16" Px64 "\n", pc_);
500void Simulator::PrintStack() {
501 StackFrameIterator frames(get_register(
FP), get_register(
SP), get_pc(),
502 ValidationPolicy::kDontValidateFrames,
504 StackFrameIterator::kNoCrossThreadIteration);
505 StackFrame*
frame = frames.NextFrame();
506 while (
frame !=
nullptr) {
507 OS::PrintErr(
"%s\n",
frame->ToCString());
508 frame = frames.NextFrame();
513void Simulator::Interpret(Instr instr) {
514 switch (instr.opcode()) {
519 InterpretAUIPC(instr);
525 InterpretJALR(instr);
528 InterpretBRANCH(instr);
531 InterpretLOAD(instr);
534 InterpretSTORE(instr);
537 InterpretOPIMM(instr);
540 InterpretOPIMM32(instr);
546 InterpretOP32(instr);
549 InterpretMISCMEM(instr);
552 InterpretSYSTEM(instr);
558 InterpretLOADFP(instr);
561 InterpretSTOREFP(instr);
564 InterpretFMADD(instr);
567 InterpretFMSUB(instr);
570 InterpretFNMADD(instr);
573 InterpretFNMSUB(instr);
576 InterpretOPFP(instr);
579 IllegalInstruction(instr);
584void Simulator::Interpret(CInstr instr) {
585 switch (instr.opcode()) {
587 uintx_t
addr = get_xreg(
SP) + instr.spload4_imm();
588 set_xreg(instr.rd(), MemoryRead<int32_t>(
addr,
SP));
593 uintx_t
addr = get_xreg(
SP) + instr.spload4_imm();
594 set_fregs(instr.frd(), MemoryRead<float>(
addr,
SP));
599 uintx_t
addr = get_xreg(
SP) + instr.spload8_imm();
600 set_xreg(instr.rd(), MemoryRead<int64_t>(
addr,
SP));
605 uintx_t
addr = get_xreg(
SP) + instr.spload8_imm();
606 set_fregd(instr.frd(), MemoryRead<double>(
addr,
SP));
610 uintx_t
addr = get_xreg(
SP) + instr.spstore4_imm();
611 MemoryWrite<uint32_t>(
addr, get_xreg(instr.rs2()),
SP);
616 uintx_t
addr = get_xreg(
SP) + instr.spstore4_imm();
617 MemoryWrite<float>(
addr, get_fregs(instr.frs2()),
SP);
622 uintx_t
addr = get_xreg(
SP) + instr.spstore8_imm();
623 MemoryWrite<uint64_t>(
addr, get_xreg(instr.rs2()),
SP);
628 uintx_t
addr = get_xreg(
SP) + instr.spstore8_imm();
629 MemoryWrite<double>(
addr, get_fregd(instr.frs2()),
SP);
633 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem4_imm();
634 set_xreg(instr.rdp(), MemoryRead<int32_t>(
addr, instr.rs1p()));
639 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem4_imm();
640 set_fregs(instr.frdp(), MemoryRead<float>(
addr, instr.rs1p()));
645 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem8_imm();
646 set_xreg(instr.rdp(), MemoryRead<int64_t>(
addr, instr.rs1p()));
651 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem8_imm();
652 set_fregd(instr.frdp(), MemoryRead<double>(
addr, instr.rs1p()));
656 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem4_imm();
657 MemoryWrite<uint32_t>(
addr, get_xreg(instr.rs2p()), instr.rs1p());
662 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem4_imm();
663 MemoryWrite<float>(
addr, get_fregs(instr.frs2p()), instr.rs1p());
668 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem8_imm();
669 MemoryWrite<uint64_t>(
addr, get_xreg(instr.rs2p()), instr.rs1p());
674 uintx_t
addr = get_xreg(instr.rs1p()) + instr.mem8_imm();
675 MemoryWrite<double>(
addr, get_fregd(instr.frs2p()), instr.rs1p());
684 set_xreg(
RA, pc_ + instr.length());
690 if ((instr.encoding() & (
C_JALR ^
C_JR)) != 0) {
691 if ((instr.rs1() ==
ZR) && (instr.rs2() ==
ZR)) {
692 InterpretEBREAK(instr);
693 }
else if (instr.rs2() ==
ZR) {
695 uintx_t
target = get_xreg(instr.rs1());
696 set_xreg(
RA, pc_ + instr.length());
701 set_xreg(instr.rd(), get_xreg(instr.rs1()) + get_xreg(instr.rs2()));
704 if ((instr.rd() !=
ZR) && (instr.rs2() !=
ZR)) {
706 set_xreg(instr.rd(), get_xreg(instr.rs2()));
707 }
else if (instr.rs2() !=
ZR) {
708 IllegalInstruction(instr);
711 pc_ = get_xreg(instr.rs1());
718 if (get_xreg(instr.rs1p()) == 0) {
719 pc_ += instr.b_imm();
724 if (get_xreg(instr.rs1p()) != 0) {
725 pc_ += instr.b_imm();
730 if (instr.rd() ==
ZR) {
731 IllegalInstruction(instr);
737 if (instr.rd() ==
SP) {
738 if (instr.i16_imm() == 0) {
739 IllegalInstruction(instr);
742 get_xreg(instr.rs1()) +
sign_extend(instr.i16_imm()));
744 }
else if ((instr.rd() ==
ZR) || (instr.u_imm() == 0)) {
745 IllegalInstruction(instr);
751 set_xreg(instr.rd(), get_xreg(instr.rs1()) + instr.i_imm());
755 uint32_t
a = get_xreg(instr.rs1());
756 uint32_t
b = instr.i_imm();
762 if (instr.i4spn_imm() == 0) {
763 IllegalInstruction(instr);
765 set_xreg(instr.rdp(), get_xreg(
SP) + instr.i4spn_imm());
769 if (instr.i_imm() == 0) {
770 IllegalInstruction(instr);
772 set_xreg(instr.rd(), get_xreg(instr.rs1())
773 << (instr.i_imm() & (XLEN - 1)));
781 if (instr.i_imm() == 0) {
782 IllegalInstruction(instr);
784 set_xreg(instr.rs1p(),
785 get_xreg(instr.rs1p()) >> (instr.i_imm() & (XLEN - 1)));
789 if (instr.i_imm() == 0) {
790 IllegalInstruction(instr);
792 set_xreg(instr.rs1p(),
793 static_cast<intx_t
>(get_xreg(instr.rs1p())) >>
794 (instr.i_imm() & (XLEN - 1)));
798 set_xreg(instr.rs1p(), get_xreg(instr.rs1p()) & instr.i_imm());
803 set_xreg(instr.rs1p(),
804 get_xreg(instr.rs1p()) & get_xreg(instr.rs2p()));
807 set_xreg(instr.rs1p(),
808 get_xreg(instr.rs1p()) | get_xreg(instr.rs2p()));
811 set_xreg(instr.rs1p(),
812 get_xreg(instr.rs1p()) ^ get_xreg(instr.rs2p()));
815 set_xreg(instr.rs1p(),
816 get_xreg(instr.rs1p()) - get_xreg(instr.rs2p()));
819 uint32_t
a = get_xreg(instr.rs1p());
820 uint32_t
b = get_xreg(instr.rs2p());
825 uint32_t
a = get_xreg(instr.rs1p());
826 uint32_t
b = get_xreg(instr.rs2p());
831 IllegalInstruction(instr);
835 IllegalInstruction(instr);
839 IllegalInstruction(instr);
841 pc_ += instr.length();
845void Simulator::InterpretLUI(Instr instr) {
846 set_xreg(instr.rd(),
sign_extend(instr.utype_imm()));
847 pc_ += instr.length();
851void Simulator::InterpretAUIPC(Instr instr) {
852 set_xreg(instr.rd(), pc_ +
sign_extend(instr.utype_imm()));
853 pc_ += instr.length();
857void Simulator::InterpretJAL(Instr instr) {
858 set_xreg(instr.rd(), pc_ + instr.length());
863void Simulator::InterpretJALR(Instr instr) {
864 uintx_t
base = get_xreg(instr.rs1());
865 uintx_t
offset =
static_cast<uintx_t
>(instr.itype_imm());
866 set_xreg(instr.rd(), pc_ + instr.length());
871void Simulator::InterpretBRANCH(Instr instr) {
872 switch (instr.funct3()) {
874 if (get_xreg(instr.rs1()) == get_xreg(instr.rs2())) {
875 pc_ += instr.btype_imm();
877 pc_ += instr.length();
881 if (get_xreg(instr.rs1()) != get_xreg(instr.rs2())) {
882 pc_ += instr.btype_imm();
884 pc_ += instr.length();
888 if (
static_cast<intx_t
>(get_xreg(instr.rs1())) <
889 static_cast<intx_t
>(get_xreg(instr.rs2()))) {
890 pc_ += instr.btype_imm();
892 pc_ += instr.length();
896 if (
static_cast<intx_t
>(get_xreg(instr.rs1())) >=
897 static_cast<intx_t
>(get_xreg(instr.rs2()))) {
898 pc_ += instr.btype_imm();
900 pc_ += instr.length();
904 if (
static_cast<uintx_t
>(get_xreg(instr.rs1())) <
905 static_cast<uintx_t
>(get_xreg(instr.rs2()))) {
906 pc_ += instr.btype_imm();
908 pc_ += instr.length();
912 if (
static_cast<uintx_t
>(get_xreg(instr.rs1())) >=
913 static_cast<uintx_t
>(get_xreg(instr.rs2()))) {
914 pc_ += instr.btype_imm();
916 pc_ += instr.length();
920 IllegalInstruction(instr);
925void Simulator::InterpretLOAD(Instr instr) {
926 uintx_t
addr = get_xreg(instr.rs1()) + instr.itype_imm();
927 switch (instr.funct3()) {
929 set_xreg(instr.rd(), MemoryRead<int8_t>(
addr, instr.rs1()));
932 set_xreg(instr.rd(), MemoryRead<int16_t>(
addr, instr.rs1()));
935 set_xreg(instr.rd(), MemoryRead<int32_t>(
addr, instr.rs1()));
938 set_xreg(instr.rd(), MemoryRead<uint8_t>(
addr, instr.rs1()));
941 set_xreg(instr.rd(), MemoryRead<uint16_t>(
addr, instr.rs1()));
945 set_xreg(instr.rd(), MemoryRead<uint32_t>(
addr, instr.rs1()));
948 set_xreg(instr.rd(), MemoryRead<int64_t>(
addr, instr.rs1()));
952 IllegalInstruction(instr);
954 pc_ += instr.length();
958void Simulator::InterpretLOADFP(Instr instr) {
959 uintx_t
addr = get_xreg(instr.rs1()) + instr.itype_imm();
960 switch (instr.funct3()) {
962 set_fregs(instr.frd(), MemoryRead<float>(
addr, instr.rs1()));
965 set_fregd(instr.frd(), MemoryRead<double>(
addr, instr.rs1()));
968 IllegalInstruction(instr);
970 pc_ += instr.length();
974void Simulator::InterpretSTORE(Instr instr) {
975 uintx_t
addr = get_xreg(instr.rs1()) + instr.stype_imm();
976 switch (instr.funct3()) {
978 MemoryWrite<uint8_t>(
addr, get_xreg(instr.rs2()), instr.rs1());
981 MemoryWrite<uint16_t>(
addr, get_xreg(instr.rs2()), instr.rs1());
984 MemoryWrite<uint32_t>(
addr, get_xreg(instr.rs2()), instr.rs1());
988 MemoryWrite<uint64_t>(
addr, get_xreg(instr.rs2()), instr.rs1());
992 IllegalInstruction(instr);
994 pc_ += instr.length();
998void Simulator::InterpretSTOREFP(Instr instr) {
999 uintx_t
addr = get_xreg(instr.rs1()) + instr.stype_imm();
1000 switch (instr.funct3()) {
1002 MemoryWrite<float>(
addr, get_fregs(instr.frs2()), instr.rs1());
1005 MemoryWrite<double>(
addr, get_fregd(instr.frs2()), instr.rs1());
1008 IllegalInstruction(instr);
1010 pc_ += instr.length();
1013static uintx_t clz(uintx_t
a) {
1014 for (
int bit = XLEN - 1; bit >= 0; bit--) {
1015 if ((
a & (
static_cast<uintx_t
>(1) << bit)) != 0) {
1016 return XLEN - bit - 1;
1022static uintx_t ctz(uintx_t
a) {
1023 for (
int bit = 0; bit < XLEN; bit++) {
1024 if ((
a & (
static_cast<uintx_t
>(1) << bit)) != 0) {
1031static uintx_t cpop(uintx_t
a) {
1033 for (
int bit = 0; bit < XLEN; bit++) {
1034 if ((
a & (
static_cast<uintx_t
>(1) << bit)) != 0) {
1041static uintx_t clzw(uint32_t
a) {
1042 for (
int bit = 32 - 1; bit >= 0; bit--) {
1043 if ((
a & (
static_cast<uint32_t
>(1) << bit)) != 0) {
1044 return 32 - bit - 1;
1050static uintx_t ctzw(uint32_t
a) {
1051 for (
int bit = 0; bit < 32; bit++) {
1052 if ((
a & (
static_cast<uint32_t
>(1) << bit)) != 0) {
1059static uintx_t cpopw(uint32_t
a) {
1061 for (
int bit = 0; bit < 32; bit++) {
1062 if ((
a & (
static_cast<uint32_t
>(1) << bit)) != 0) {
1069static intx_t
max(intx_t
a, intx_t
b) {
1070 return a >
b ?
a :
b;
1072static uintx_t maxu(uintx_t
a, uintx_t
b) {
1073 return a >
b ?
a :
b;
1075static intx_t
min(intx_t
a, intx_t
b) {
1076 return a <
b ?
a :
b;
1078static uintx_t minu(uintx_t
a, uintx_t
b) {
1079 return a <
b ?
a :
b;
1081static uintx_t clmul(uintx_t
a, uintx_t
b) {
1083 for (
int bit = 0; bit < XLEN; bit++) {
1084 if (((
b >> bit) & 1) != 0) {
1090static uintx_t clmulh(uintx_t
a, uintx_t
b) {
1092 for (
int bit = 1; bit < XLEN; bit++) {
1093 if (((
b >> bit) & 1) != 0) {
1099static uintx_t clmulr(uintx_t
a, uintx_t
b) {
1101 for (
int bit = 0; bit < XLEN; bit++) {
1102 if (((
b >> bit) & 1) != 0) {
1103 result ^=
a >> (XLEN - bit - 1);
1108static uintx_t sextb(uintx_t
a) {
1109 return static_cast<intx_t
>(
a << (XLEN - 8)) >> (XLEN - 8);
1111static uintx_t sexth(uintx_t
a) {
1112 return static_cast<intx_t
>(
a << (XLEN - 16)) >> (XLEN - 16);
1114static uintx_t zexth(uintx_t
a) {
1115 return a << (XLEN - 16) >> (XLEN - 16);
1117static uintx_t ror(uintx_t
a, uintx_t
b) {
1118 uintx_t r =
b & (XLEN - 1);
1119 uintx_t l = (XLEN - r) & (XLEN - 1);
1120 return (
a << l) | (
a >> r);
1122static uintx_t rol(uintx_t
a, uintx_t
b) {
1123 uintx_t l =
b & (XLEN - 1);
1124 uintx_t r = (XLEN - l) & (XLEN - 1);
1125 return (
a << l) | (
a >> r);
1127static uintx_t rorw(uintx_t
a, uintx_t
b) {
1128 uint32_t r =
b & (XLEN - 1);
1129 uint32_t l = (XLEN - r) & (XLEN - 1);
1133static uintx_t rolw(uintx_t
a, uintx_t
b) {
1134 uint32_t l =
b & (XLEN - 1);
1135 uint32_t r = (XLEN - l) & (XLEN - 1);
1139static uintx_t orcb(uintx_t
a) {
1141 for (
int shift = 0; shift < XLEN; shift += 8) {
1142 if (((
a >> shift) & 0xFF) != 0) {
1143 result |=
static_cast<uintx_t
>(0xFF) << shift;
1148static uintx_t rev8(uintx_t
a) {
1150 for (
int shift = 0; shift < XLEN; shift += 8) {
1152 result |= (
a >> shift) & 0xFF;
1156static uintx_t bclr(uintx_t
a, uintx_t
b) {
1157 return a & ~(
static_cast<uintx_t
>(1) << (
b & (XLEN - 1)));
1159static uintx_t bext(uintx_t
a, uintx_t
b) {
1160 return (
a >> (
b & (XLEN - 1))) & 1;
1162static uintx_t binv(uintx_t
a, uintx_t
b) {
1163 return a ^ (
static_cast<uintx_t
>(1) << (
b & (XLEN - 1)));
1165static uintx_t bset(uintx_t
a, uintx_t
b) {
1166 return a | (
static_cast<uintx_t
>(1) << (
b & (XLEN - 1)));
1170void Simulator::InterpretOPIMM(Instr instr) {
1171 switch (instr.funct3()) {
1173 set_xreg(instr.rd(), get_xreg(instr.rs1()) + instr.itype_imm());
1176 set_xreg(instr.rd(),
static_cast<intx_t
>(get_xreg(instr.rs1())) <
1177 static_cast<intx_t
>(instr.itype_imm())
1183 set_xreg(instr.rd(),
static_cast<uintx_t
>(get_xreg(instr.rs1())) <
1184 static_cast<uintx_t
>(instr.itype_imm())
1189 set_xreg(instr.rd(), get_xreg(instr.rs1()) ^ instr.itype_imm());
1192 set_xreg(instr.rd(), get_xreg(instr.rs1()) | instr.itype_imm());
1195 set_xreg(instr.rd(), get_xreg(instr.rs1()) & instr.itype_imm());
1198 if (instr.funct7() ==
COUNT) {
1199 if (instr.shamt() == 0b00000) {
1200 set_xreg(instr.rd(), clz(get_xreg(instr.rs1())));
1201 }
else if (instr.shamt() == 0b00001) {
1202 set_xreg(instr.rd(), ctz(get_xreg(instr.rs1())));
1203 }
else if (instr.shamt() == 0b00010) {
1204 set_xreg(instr.rd(), cpop(get_xreg(instr.rs1())));
1205 }
else if (instr.shamt() == 0b00100) {
1206 set_xreg(instr.rd(), sextb(get_xreg(instr.rs1())));
1207 }
else if (instr.shamt() == 0b00101) {
1208 set_xreg(instr.rd(), sexth(get_xreg(instr.rs1())));
1210 IllegalInstruction(instr);
1212 }
else if ((instr.funct7() & 0b1111110) ==
BCLRBEXT) {
1213 set_xreg(instr.rd(), bclr(get_xreg(instr.rs1()), instr.shamt()));
1214 }
else if ((instr.funct7() & 0b1111110) ==
BINV) {
1215 set_xreg(instr.rd(), binv(get_xreg(instr.rs1()), instr.shamt()));
1216 }
else if ((instr.funct7() & 0b1111110) ==
BSET) {
1217 set_xreg(instr.rd(), bset(get_xreg(instr.rs1()), instr.shamt()));
1219 set_xreg(instr.rd(), get_xreg(instr.rs1()) << instr.shamt());
1223 if ((instr.funct7() & 0b1111110) ==
SRA) {
1224 set_xreg(instr.rd(),
1225 static_cast<intx_t
>(get_xreg(instr.rs1())) >> instr.shamt());
1226 }
else if ((instr.funct7() & 0b1111110) ==
ROTATE) {
1227 set_xreg(instr.rd(), ror(get_xreg(instr.rs1()), instr.shamt()));
1228 }
else if (instr.funct7() == 0b0010100) {
1229 set_xreg(instr.rd(), orcb(get_xreg(instr.rs1())));
1231 }
else if (instr.funct7() == 0b0110100) {
1233 }
else if (instr.funct7() == 0b0110101) {
1235 set_xreg(instr.rd(), rev8(get_xreg(instr.rs1())));
1236 }
else if ((instr.funct7() & 0b1111110) ==
BCLRBEXT) {
1237 set_xreg(instr.rd(), bext(get_xreg(instr.rs1()), instr.shamt()));
1239 set_xreg(instr.rd(),
1240 static_cast<uintx_t
>(get_xreg(instr.rs1())) >> instr.shamt());
1244 IllegalInstruction(instr);
1246 pc_ += instr.length();
1250void Simulator::InterpretOPIMM32(Instr instr) {
1251 switch (instr.funct3()) {
1253 uint32_t
a = get_xreg(instr.rs1());
1254 uint32_t
b = instr.itype_imm();
1259 if (instr.funct7() ==
SLLIUW) {
1260 uintx_t
a =
static_cast<uint32_t
>(get_xreg(instr.rs1()));
1261 uintx_t
b = instr.shamt();
1262 set_xreg(instr.rd(),
a <<
b);
1263 }
else if (instr.funct7() ==
COUNT) {
1264 if (instr.shamt() == 0b00000) {
1265 set_xreg(instr.rd(), clzw(get_xreg(instr.rs1())));
1266 }
else if (instr.shamt() == 0b00001) {
1267 set_xreg(instr.rd(), ctzw(get_xreg(instr.rs1())));
1268 }
else if (instr.shamt() == 0b00010) {
1269 set_xreg(instr.rd(), cpopw(get_xreg(instr.rs1())));
1271 IllegalInstruction(instr);
1274 uint32_t
a = get_xreg(instr.rs1());
1275 uint32_t
b = instr.shamt();
1281 if (instr.funct7() ==
SRA) {
1282 int32_t
a = get_xreg(instr.rs1());
1283 int32_t
b = instr.shamt();
1285 }
else if (instr.funct7() ==
ROTATE) {
1286 set_xreg(instr.rd(), rorw(get_xreg(instr.rs1()), instr.shamt()));
1288 uint32_t
a = get_xreg(instr.rs1());
1289 uint32_t
b = instr.shamt();
1294 IllegalInstruction(instr);
1296 pc_ += instr.length();
1300void Simulator::InterpretOP(Instr instr) {
1301 switch (instr.funct7()) {
1303 InterpretOP_0(instr);
1306 InterpretOP_SUB(instr);
1309 InterpretOP_MULDIV(instr);
1312 InterpretOP_SHADD(instr);
1315 InterpretOP_MINMAXCLMUL(instr);
1318 InterpretOP_ROTATE(instr);
1321 InterpretOP_BCLRBEXT(instr);
1324 set_xreg(instr.rd(), binv(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1325 pc_ += instr.length();
1328 set_xreg(instr.rd(), bset(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1329 pc_ += instr.length();
1333 set_xreg(instr.rd(), zexth(get_xreg(instr.rs1())));
1334 pc_ += instr.length();
1338 IllegalInstruction(instr);
1343void Simulator::InterpretOP_0(Instr instr) {
1344 switch (instr.funct3()) {
1346 set_xreg(instr.rd(), get_xreg(instr.rs1()) + get_xreg(instr.rs2()));
1349 uintx_t shamt = get_xreg(instr.rs2()) & (XLEN - 1);
1350 set_xreg(instr.rd(), get_xreg(instr.rs1()) << shamt);
1354 set_xreg(instr.rd(),
static_cast<intx_t
>(get_xreg(instr.rs1())) <
1355 static_cast<intx_t
>(get_xreg(instr.rs2()))
1360 set_xreg(instr.rd(),
static_cast<uintx_t
>(get_xreg(instr.rs1())) <
1361 static_cast<uintx_t
>(get_xreg(instr.rs2()))
1366 set_xreg(instr.rd(), get_xreg(instr.rs1()) ^ get_xreg(instr.rs2()));
1369 uintx_t shamt = get_xreg(instr.rs2()) & (XLEN - 1);
1370 set_xreg(instr.rd(),
1371 static_cast<uintx_t
>(get_xreg(instr.rs1())) >> shamt);
1375 set_xreg(instr.rd(), get_xreg(instr.rs1()) | get_xreg(instr.rs2()));
1378 set_xreg(instr.rd(), get_xreg(instr.rs1()) & get_xreg(instr.rs2()));
1381 IllegalInstruction(instr);
1383 pc_ += instr.length();
1386static intx_t mul(intx_t
a, intx_t
b) {
1387 return static_cast<uintx_t
>(
a) *
static_cast<uintx_t
>(
b);
1390static intx_t mulh(intx_t
a, intx_t
b) {
1391 const uintx_t kLoMask = (
static_cast<uintx_t
>(1) << (XLEN / 2)) - 1;
1392 const uintx_t kHiShift = XLEN / 2;
1394 uintx_t a_lo =
a & kLoMask;
1395 intx_t a_hi =
a >> kHiShift;
1396 uintx_t b_lo =
b & kLoMask;
1397 intx_t b_hi =
b >> kHiShift;
1399 uintx_t
x = a_lo * b_lo;
1400 intx_t
y = a_hi * b_lo;
1401 intx_t z = a_lo * b_hi;
1402 intx_t
w = a_hi * b_hi;
1404 intx_t r0 = (
x >> kHiShift) +
y;
1405 intx_t r1 = (r0 & kLoMask) + z;
1406 return w + (r0 >> kHiShift) + (r1 >> kHiShift);
1409static uintx_t mulhu(uintx_t
a, uintx_t
b) {
1410 const uintx_t kLoMask = (
static_cast<uintx_t
>(1) << (XLEN / 2)) - 1;
1411 const uintx_t kHiShift = XLEN / 2;
1413 uintx_t a_lo =
a & kLoMask;
1414 uintx_t a_hi =
a >> kHiShift;
1415 uintx_t b_lo =
b & kLoMask;
1416 uintx_t b_hi =
b >> kHiShift;
1418 uintx_t
x = a_lo * b_lo;
1419 uintx_t
y = a_hi * b_lo;
1420 uintx_t z = a_lo * b_hi;
1421 uintx_t
w = a_hi * b_hi;
1423 uintx_t r0 = (
x >> kHiShift) +
y;
1424 uintx_t r1 = (r0 & kLoMask) + z;
1425 return w + (r0 >> kHiShift) + (r1 >> kHiShift);
1428static uintx_t mulhsu(intx_t
a, uintx_t
b) {
1429 const uintx_t kLoMask = (
static_cast<uintx_t
>(1) << (XLEN / 2)) - 1;
1430 const uintx_t kHiShift = XLEN / 2;
1432 uintx_t a_lo =
a & kLoMask;
1433 intx_t a_hi =
a >> kHiShift;
1434 uintx_t b_lo =
b & kLoMask;
1435 uintx_t b_hi =
b >> kHiShift;
1437 uintx_t
x = a_lo * b_lo;
1438 intx_t
y = a_hi * b_lo;
1439 uintx_t z = a_lo * b_hi;
1440 intx_t
w = a_hi * b_hi;
1442 intx_t r0 = (
x >> kHiShift) +
y;
1443 uintx_t r1 = (r0 & kLoMask) + z;
1444 return w + (r0 >> kHiShift) + (r1 >> kHiShift);
1447static intx_t div(intx_t
a, intx_t
b) {
1450 }
else if (
b == -1 &&
a == kMinIntX) {
1457static uintx_t divu(uintx_t
a, uintx_t
b) {
1465static intx_t rem(intx_t
a, intx_t
b) {
1468 }
else if (
b == -1 &&
a == kMinIntX) {
1475static uintx_t remu(uintx_t
a, uintx_t
b) {
1484static int32_t mulw(int32_t
a, int32_t
b) {
1488static int32_t divw(int32_t
a, int32_t
b) {
1498static uint32_t divuw(uint32_t
a, uint32_t
b) {
1506static int32_t remw(int32_t
a, int32_t
b) {
1516static uint32_t remuw(uint32_t
a, uint32_t
b) {
1526void Simulator::InterpretOP_MULDIV(Instr instr) {
1527 switch (instr.funct3()) {
1529 set_xreg(instr.rd(), mul(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1532 set_xreg(instr.rd(), mulh(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1535 set_xreg(instr.rd(),
1536 mulhsu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1539 set_xreg(instr.rd(), mulhu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1542 set_xreg(instr.rd(), div(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1545 set_xreg(instr.rd(), divu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1548 set_xreg(instr.rd(), rem(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1551 set_xreg(instr.rd(), remu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1554 IllegalInstruction(instr);
1556 pc_ += instr.length();
1560void Simulator::InterpretOP_SUB(Instr instr) {
1561 switch (instr.funct3()) {
1563 set_xreg(instr.rd(), get_xreg(instr.rs1()) - get_xreg(instr.rs2()));
1566 uintx_t shamt = get_xreg(instr.rs2()) & (XLEN - 1);
1567 set_xreg(instr.rd(),
static_cast<intx_t
>(get_xreg(instr.rs1())) >> shamt);
1571 set_xreg(instr.rd(), get_xreg(instr.rs1()) & ~get_xreg(instr.rs2()));
1574 set_xreg(instr.rd(), get_xreg(instr.rs1()) | ~get_xreg(instr.rs2()));
1577 set_xreg(instr.rd(), get_xreg(instr.rs1()) ^ ~get_xreg(instr.rs2()));
1580 IllegalInstruction(instr);
1582 pc_ += instr.length();
1586void Simulator::InterpretOP_SHADD(Instr instr) {
1587 switch (instr.funct3()) {
1589 set_xreg(instr.rd(),
1590 (get_xreg(instr.rs1()) << 1) + get_xreg(instr.rs2()));
1593 set_xreg(instr.rd(),
1594 (get_xreg(instr.rs1()) << 2) + get_xreg(instr.rs2()));
1597 set_xreg(instr.rd(),
1598 (get_xreg(instr.rs1()) << 3) + get_xreg(instr.rs2()));
1601 IllegalInstruction(instr);
1603 pc_ += instr.length();
1607void Simulator::InterpretOP_MINMAXCLMUL(Instr instr) {
1608 switch (instr.funct3()) {
1610 set_xreg(instr.rd(),
max(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1613 set_xreg(instr.rd(), maxu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1616 set_xreg(instr.rd(),
min(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1619 set_xreg(instr.rd(), minu(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1622 set_xreg(instr.rd(), clmul(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1625 set_xreg(instr.rd(),
1626 clmulh(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1629 set_xreg(instr.rd(),
1630 clmulr(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1633 IllegalInstruction(instr);
1635 pc_ += instr.length();
1639void Simulator::InterpretOP_ROTATE(Instr instr) {
1640 switch (instr.funct3()) {
1642 set_xreg(instr.rd(), ror(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1645 set_xreg(instr.rd(), rol(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1648 IllegalInstruction(instr);
1650 pc_ += instr.length();
1654void Simulator::InterpretOP_BCLRBEXT(Instr instr) {
1655 switch (instr.funct3()) {
1657 set_xreg(instr.rd(), bclr(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1660 set_xreg(instr.rd(), bext(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1663 IllegalInstruction(instr);
1665 pc_ += instr.length();
1669void Simulator::InterpretOP32(Instr instr) {
1670 switch (instr.funct7()) {
1673 InterpretOP32_0(instr);
1676 InterpretOP32_SUB(instr);
1679 InterpretOP32_MULDIV(instr);
1682 InterpretOP32_SHADD(instr);
1685 InterpretOP32_ADDUW(instr);
1688 InterpretOP32_ROTATE(instr);
1692 IllegalInstruction(instr);
1697void Simulator::InterpretOP32_0(Instr instr) {
1698 switch (instr.funct3()) {
1701 uint32_t
a = get_xreg(instr.rs1());
1702 uint32_t
b = get_xreg(instr.rs2());
1707 uint32_t
a = get_xreg(instr.rs1());
1708 uint32_t
b = get_xreg(instr.rs2()) & (32 - 1);
1713 uint32_t
b = get_xreg(instr.rs2()) & (32 - 1);
1714 uint32_t
a = get_xreg(instr.rs1());
1720 IllegalInstruction(instr);
1722 pc_ += instr.length();
1726void Simulator::InterpretOP32_SUB(Instr instr) {
1727 switch (instr.funct3()) {
1730 uint32_t
a = get_xreg(instr.rs1());
1731 uint32_t
b = get_xreg(instr.rs2());
1736 uint32_t
b = get_xreg(instr.rs2()) & (32 - 1);
1737 int32_t
a = get_xreg(instr.rs1());
1743 IllegalInstruction(instr);
1745 pc_ += instr.length();
1749void Simulator::InterpretOP32_MULDIV(Instr instr) {
1750 switch (instr.funct3()) {
1753 set_xreg(instr.rd(),
1754 sign_extend(mulw(get_xreg(instr.rs1()), get_xreg(instr.rs2()))));
1757 set_xreg(instr.rd(),
1758 sign_extend(divw(get_xreg(instr.rs1()), get_xreg(instr.rs2()))));
1761 set_xreg(instr.rd(),
sign_extend(divuw(get_xreg(instr.rs1()),
1762 get_xreg(instr.rs2()))));
1765 set_xreg(instr.rd(),
1766 sign_extend(remw(get_xreg(instr.rs1()), get_xreg(instr.rs2()))));
1769 set_xreg(instr.rd(),
sign_extend(remuw(get_xreg(instr.rs1()),
1770 get_xreg(instr.rs2()))));
1774 IllegalInstruction(instr);
1776 pc_ += instr.length();
1780void Simulator::InterpretOP32_SHADD(Instr instr) {
1781 switch (instr.funct3()) {
1783 uintx_t
a =
static_cast<uint32_t
>(get_xreg(instr.rs1()));
1784 uintx_t
b = get_xreg(instr.rs2());
1785 set_xreg(instr.rd(), (
a << 1) +
b);
1789 uintx_t
a =
static_cast<uint32_t
>(get_xreg(instr.rs1()));
1790 uintx_t
b = get_xreg(instr.rs2());
1791 set_xreg(instr.rd(), (
a << 2) +
b);
1795 uintx_t
a =
static_cast<uint32_t
>(get_xreg(instr.rs1()));
1796 uintx_t
b = get_xreg(instr.rs2());
1797 set_xreg(instr.rd(), (
a << 3) +
b);
1801 IllegalInstruction(instr);
1803 pc_ += instr.length();
1807void Simulator::InterpretOP32_ADDUW(Instr instr) {
1808 switch (instr.funct3()) {
1811 uintx_t
a =
static_cast<uint32_t
>(get_xreg(instr.rs1()));
1812 uintx_t
b = get_xreg(instr.rs2());
1813 set_xreg(instr.rd(),
a +
b);
1817 set_xreg(instr.rd(), zexth(get_xreg(instr.rs1())));
1821 IllegalInstruction(instr);
1823 pc_ += instr.length();
1827void Simulator::InterpretOP32_ROTATE(Instr instr) {
1828 switch (instr.funct3()) {
1830 set_xreg(instr.rd(), rorw(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1833 set_xreg(instr.rd(), rolw(get_xreg(instr.rs1()), get_xreg(instr.rs2())));
1836 IllegalInstruction(instr);
1838 pc_ += instr.length();
1841void Simulator::InterpretMISCMEM(Instr instr) {
1842 switch (instr.funct3()) {
1844 std::atomic_thread_fence(std::memory_order_acq_rel);
1850 IllegalInstruction(instr);
1852 pc_ += instr.length();
1855void Simulator::InterpretSYSTEM(Instr instr) {
1856 switch (instr.funct3()) {
1858 switch (instr.funct12()) {
1860 InterpretECALL(instr);
1863 InterpretEBREAK(instr);
1866 IllegalInstruction(instr);
1870 if (instr.rd() ==
ZR) {
1872 CSRWrite(instr.csr(), get_xreg(instr.rs1()));
1874 intx_t
result = CSRRead(instr.csr());
1875 CSRWrite(instr.csr(), get_xreg(instr.rs1()));
1876 set_xreg(instr.rd(),
result);
1881 intx_t
result = CSRRead(instr.csr());
1882 if (instr.rs1() ==
ZR) {
1885 CSRSet(instr.csr(), get_xreg(instr.rs1()));
1887 set_xreg(instr.rd(),
result);
1891 intx_t
result = CSRRead(instr.csr());
1892 if (instr.rs1() ==
ZR) {
1895 CSRClear(instr.csr(), get_xreg(instr.rs1()));
1897 set_xreg(instr.rd(),
result);
1901 if (instr.rd() ==
ZR) {
1903 CSRWrite(instr.csr(), instr.zimm());
1905 intx_t
result = CSRRead(instr.csr());
1906 CSRWrite(instr.csr(), instr.zimm());
1907 set_xreg(instr.rd(),
result);
1912 intx_t
result = CSRRead(instr.csr());
1913 if (instr.zimm() == 0) {
1916 CSRSet(instr.csr(), instr.zimm());
1918 set_xreg(instr.rd(),
result);
1922 intx_t
result = CSRRead(instr.csr());
1923 if (instr.zimm() == 0) {
1926 CSRClear(instr.csr(), instr.zimm());
1928 set_xreg(instr.rd(),
result);
1932 IllegalInstruction(instr);
1934 pc_ += instr.length();
1938typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1941typedef intx_t (*SimulatorLeafRuntimeCall)(intx_t r0,
1955static intx_t InvokeLeafRuntime(SimulatorLeafRuntimeCall
target,
1964 return target(r0, r1, r2, r3, r4, r5, r6, r7);
1968typedef double (*SimulatorLeafFloatRuntimeCall)(
double d0,
1982static
double InvokeFloatLeafRuntime(SimulatorLeafFloatRuntimeCall
target,
1991 return target(d0, d1, d2, d3, d4, d5, d6, d7);
1998void Simulator::InterpretECALL(Instr instr) {
1999 if (instr.rs1() !=
ZR) {
2001 if (
true || IsTracingExecution()) {
2002 Object& obj = Object::Handle(
2003 static_cast<ObjectPtr
>(
static_cast<uword>(get_xreg(instr.rs1()))));
2006 FLAG_trace_sim_after = 1;
2008 pc_ += instr.length();
2013 if (!Utils::IsAligned(get_xreg(
SP), 16)) {
2016 FATAL(
"Stack misaligned at call to C function");
2019 SimulatorSetjmpBuffer
buffer(
this);
2020 if (!setjmp(
buffer.buffer_)) {
2021 uintx_t saved_ra = get_xreg(
RA);
2022 Redirection* redirection = Redirection::FromECallInstruction(pc_);
2023 uword external = redirection->external_function();
2024 if (IsTracingExecution()) {
2025 THR_Print(
"Call to host function at 0x%" Pd "\n", external);
2028 if (redirection->call_kind() == kRuntimeCall) {
2029 NativeArguments* arguments =
2030 reinterpret_cast<NativeArguments*
>(get_register(
A0));
2031 SimulatorRuntimeCall
target =
2032 reinterpret_cast<SimulatorRuntimeCall
>(external);
2034 ClobberVolatileRegisters();
2035 }
else if (redirection->call_kind() == kLeafRuntimeCall) {
2036 ASSERT((0 <= redirection->argument_count()) &&
2037 (redirection->argument_count() <= 8));
2038 SimulatorLeafRuntimeCall
target =
2039 reinterpret_cast<SimulatorLeafRuntimeCall
>(external);
2040 const intx_t r0 = get_register(
A0);
2041 const intx_t r1 = get_register(
A1);
2042 const intx_t r2 = get_register(
A2);
2043 const intx_t r3 = get_register(
A3);
2044 const intx_t r4 = get_register(
A4);
2045 const intx_t r5 = get_register(
A5);
2046 const intx_t r6 = get_register(
A6);
2047 const intx_t r7 = get_register(
A7);
2049 InvokeLeafRuntime(
target, r0, r1, r2, r3, r4, r5, r6, r7);
2050 ClobberVolatileRegisters();
2052 }
else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
2053 ASSERT((0 <= redirection->argument_count()) &&
2054 (redirection->argument_count() <= 8));
2055 SimulatorLeafFloatRuntimeCall
target =
2056 reinterpret_cast<SimulatorLeafFloatRuntimeCall
>(external);
2057 const double d0 = get_fregd(
FA0);
2058 const double d1 = get_fregd(
FA1);
2059 const double d2 = get_fregd(
FA2);
2060 const double d3 = get_fregd(
FA3);
2061 const double d4 = get_fregd(
FA4);
2062 const double d5 = get_fregd(
FA5);
2063 const double d6 = get_fregd(
FA6);
2064 const double d7 = get_fregd(
FA7);
2066 InvokeFloatLeafRuntime(
target, d0, d1, d2, d3, d4, d5, d6, d7);
2067 ClobberVolatileRegisters();
2068 set_fregd(
FA0, res);
2069 }
else if (redirection->call_kind() == kNativeCallWrapper) {
2070 SimulatorNativeCallWrapper wrapper =
2071 reinterpret_cast<SimulatorNativeCallWrapper
>(external);
2076 wrapper(arguments,
target);
2077 ClobberVolatileRegisters();
2089void Simulator::InterpretAMO(Instr instr) {
2090 switch (instr.funct3()) {
2092 InterpretAMO8(instr);
2095 InterpretAMO16(instr);
2098 InterpretAMO32(instr);
2101 InterpretAMO64(instr);
2104 IllegalInstruction(instr);
2111template <
typename type>
2112void Simulator::InterpretLR(Instr instr) {
2113 uintx_t
addr = get_xreg(instr.rs1());
2114 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2115 FATAL(
"Misaligned atomic memory operation");
2117 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2118 reserved_address_ =
addr;
2119 reserved_value_ = atomic->load(instr.memory_order());
2120 set_xreg(instr.rd(), reserved_value_);
2123template <
typename type>
2124void Simulator::InterpretSC(Instr instr) {
2125 uintx_t
addr = get_xreg(instr.rs1());
2126 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2127 FATAL(
"Misaligned atomic memory operation");
2129 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2130 if (
addr != reserved_address_) {
2131 set_xreg(instr.rd(), 1);
2134 if ((random_.NextUInt32() % 16) == 0) {
2135 set_xreg(instr.rd(), 1);
2138 type expected = reserved_value_;
2139 type desired = get_xreg(instr.rs2());
2141 atomic->compare_exchange_strong(expected, desired, instr.memory_order());
2142 set_xreg(instr.rd(), success ? 0 : 1);
2145template <
typename type>
2146void Simulator::InterpretAMOSWAP(Instr instr) {
2147 uintx_t
addr = get_xreg(instr.rs1());
2148 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2149 FATAL(
"Misaligned atomic memory operation");
2151 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2152 type desired = get_xreg(instr.rs2());
2153 type result = atomic->exchange(desired, instr.memory_order());
2157template <
typename type>
2158void Simulator::InterpretAMOADD(Instr instr) {
2159 uintx_t
addr = get_xreg(instr.rs1());
2160 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2161 FATAL(
"Misaligned atomic memory operation");
2163 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2164 type arg = get_xreg(instr.rs2());
2165 type result = atomic->fetch_add(arg, instr.memory_order());
2169template <
typename type>
2170void Simulator::InterpretAMOXOR(Instr instr) {
2171 uintx_t
addr = get_xreg(instr.rs1());
2172 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2173 FATAL(
"Misaligned atomic memory operation");
2175 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2176 type arg = get_xreg(instr.rs2());
2177 type result = atomic->fetch_xor(arg, instr.memory_order());
2181template <
typename type>
2182void Simulator::InterpretAMOAND(Instr instr) {
2183 uintx_t
addr = get_xreg(instr.rs1());
2184 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2185 FATAL(
"Misaligned atomic memory operation");
2187 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2188 type arg = get_xreg(instr.rs2());
2189 type result = atomic->fetch_and(arg, instr.memory_order());
2193template <
typename type>
2194void Simulator::InterpretAMOOR(Instr instr) {
2195 uintx_t
addr = get_xreg(instr.rs1());
2196 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2197 FATAL(
"Misaligned atomic memory operation");
2199 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2200 type arg = get_xreg(instr.rs2());
2201 type result = atomic->fetch_or(arg, instr.memory_order());
2205template <
typename type>
2206void Simulator::InterpretAMOMIN(Instr instr) {
2207 uintx_t
addr = get_xreg(instr.rs1());
2208 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2209 FATAL(
"Misaligned atomic memory operation");
2211 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2212 type expected = atomic->load(std::memory_order_relaxed);
2218 !atomic->compare_exchange_weak(expected, desired, instr.memory_order()));
2222template <
typename type>
2223void Simulator::InterpretAMOMAX(Instr instr) {
2224 uintx_t
addr = get_xreg(instr.rs1());
2225 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2226 FATAL(
"Misaligned atomic memory operation");
2228 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2229 type expected = atomic->load(std::memory_order_relaxed);
2235 !atomic->compare_exchange_weak(expected, desired, instr.memory_order()));
2239template <
typename type>
2240void Simulator::InterpretLOADORDERED(Instr instr) {
2241 uintx_t
addr = get_xreg(instr.rs1());
2242 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2243 FATAL(
"Misaligned atomic memory operation");
2245 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2246 type value = atomic->load(instr.memory_order());
2250template <
typename type>
2251void Simulator::InterpretSTOREORDERED(Instr instr) {
2252 uintx_t
addr = get_xreg(instr.rs1());
2253 if ((
addr & (
sizeof(
type) - 1)) != 0) {
2254 FATAL(
"Misaligned atomic memory operation");
2257 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2258 atomic->store(
value, instr.memory_order());
2261void Simulator::InterpretAMO8(Instr instr) {
2262 switch (instr.funct5()) {
2264 InterpretLOADORDERED<int8_t>(instr);
2267 InterpretSTOREORDERED<int8_t>(instr);
2270 IllegalInstruction(instr);
2272 pc_ += instr.length();
2275void Simulator::InterpretAMO16(Instr instr) {
2276 switch (instr.funct5()) {
2278 InterpretLOADORDERED<int16_t>(instr);
2281 InterpretSTOREORDERED<int16_t>(instr);
2284 IllegalInstruction(instr);
2286 pc_ += instr.length();
2289void Simulator::InterpretAMO32(Instr instr) {
2290 switch (instr.funct5()) {
2292 InterpretLR<int32_t>(instr);
2295 InterpretSC<int32_t>(instr);
2298 InterpretAMOSWAP<int32_t>(instr);
2301 InterpretAMOADD<int32_t>(instr);
2304 InterpretAMOXOR<int32_t>(instr);
2307 InterpretAMOAND<int32_t>(instr);
2310 InterpretAMOOR<int32_t>(instr);
2313 InterpretAMOMIN<int32_t>(instr);
2316 InterpretAMOMAX<int32_t>(instr);
2319 InterpretAMOMIN<uint32_t>(instr);
2322 InterpretAMOMAX<uint32_t>(instr);
2325 InterpretLOADORDERED<int32_t>(instr);
2328 InterpretSTOREORDERED<int32_t>(instr);
2331 IllegalInstruction(instr);
2333 pc_ += instr.length();
2336void Simulator::InterpretAMO64(Instr instr) {
2337 switch (instr.funct5()) {
2340 InterpretLR<int64_t>(instr);
2343 InterpretSC<int64_t>(instr);
2346 InterpretAMOSWAP<int64_t>(instr);
2349 InterpretAMOADD<int64_t>(instr);
2352 InterpretAMOXOR<int64_t>(instr);
2355 InterpretAMOAND<int64_t>(instr);
2358 InterpretAMOOR<int64_t>(instr);
2361 InterpretAMOMIN<int64_t>(instr);
2364 InterpretAMOMAX<int64_t>(instr);
2367 InterpretAMOMIN<uint64_t>(instr);
2370 InterpretAMOMAX<uint64_t>(instr);
2373 InterpretLOADORDERED<int64_t>(instr);
2376 InterpretSTOREORDERED<int64_t>(instr);
2380 IllegalInstruction(instr);
2382 pc_ += instr.length();
2385void Simulator::InterpretFMADD(Instr instr) {
2386 switch (instr.funct2()) {
2388 float rs1 = get_fregs(instr.frs1());
2389 float rs2 = get_fregs(instr.frs2());
2390 float rs3 = get_fregs(instr.frs3());
2391 set_fregs(instr.frd(), (rs1 * rs2) + rs3);
2395 double rs1 = get_fregd(instr.frs1());
2396 double rs2 = get_fregd(instr.frs2());
2397 double rs3 = get_fregd(instr.frs3());
2398 set_fregd(instr.frd(), (rs1 * rs2) + rs3);
2402 IllegalInstruction(instr);
2404 pc_ += instr.length();
2407void Simulator::InterpretFMSUB(Instr instr) {
2408 switch (instr.funct2()) {
2410 float rs1 = get_fregs(instr.frs1());
2411 float rs2 = get_fregs(instr.frs2());
2412 float rs3 = get_fregs(instr.frs3());
2413 set_fregs(instr.frd(), (rs1 * rs2) - rs3);
2417 double rs1 = get_fregd(instr.frs1());
2418 double rs2 = get_fregd(instr.frs2());
2419 double rs3 = get_fregd(instr.frs3());
2420 set_fregd(instr.frd(), (rs1 * rs2) - rs3);
2424 IllegalInstruction(instr);
2426 pc_ += instr.length();
2429void Simulator::InterpretFNMSUB(Instr instr) {
2430 switch (instr.funct2()) {
2432 float rs1 = get_fregs(instr.frs1());
2433 float rs2 = get_fregs(instr.frs2());
2434 float rs3 = get_fregs(instr.frs3());
2435 set_fregs(instr.frd(), -(rs1 * rs2) + rs3);
2439 double rs1 = get_fregd(instr.frs1());
2440 double rs2 = get_fregd(instr.frs2());
2441 double rs3 = get_fregd(instr.frs3());
2442 set_fregd(instr.frd(), -(rs1 * rs2) + rs3);
2446 IllegalInstruction(instr);
2448 pc_ += instr.length();
2451void Simulator::InterpretFNMADD(Instr instr) {
2452 switch (instr.funct2()) {
2454 float rs1 = get_fregs(instr.frs1());
2455 float rs2 = get_fregs(instr.frs2());
2456 float rs3 = get_fregs(instr.frs3());
2457 set_fregs(instr.frd(), -(rs1 * rs2) - rs3);
2461 double rs1 = get_fregd(instr.frs1());
2462 double rs2 = get_fregd(instr.frs2());
2463 double rs3 = get_fregd(instr.frs3());
2464 set_fregd(instr.frd(), -(rs1 * rs2) - rs3);
2468 IllegalInstruction(instr);
2470 pc_ += instr.length();
2477static double rv_fmin(
double x,
double y) {
2478 if (isnan(
x) && isnan(
y))
return std::numeric_limits<double>::quiet_NaN();
2479 if (isnan(
x))
return y;
2480 if (isnan(
y))
return x;
2481 if (
x ==
y)
return signbit(
x) ?
x :
y;
2485static double rv_fmax(
double x,
double y) {
2486 if (isnan(
x) && isnan(
y))
return std::numeric_limits<double>::quiet_NaN();
2487 if (isnan(
x))
return y;
2488 if (isnan(
y))
return x;
2489 if (
x ==
y)
return signbit(
x) ?
y :
x;
2493static float rv_fminf(
float x,
float y) {
2494 if (isnan(
x) && isnan(
y))
return std::numeric_limits<float>::quiet_NaN();
2495 if (isnan(
x))
return y;
2496 if (isnan(
y))
return x;
2497 if (
x ==
y)
return signbit(
x) ?
x :
y;
2501static float rv_fmaxf(
float x,
float y) {
2502 if (isnan(
x) && isnan(
y))
return std::numeric_limits<float>::quiet_NaN();
2503 if (isnan(
x))
return y;
2504 if (isnan(
y))
return x;
2505 if (
x ==
y)
return signbit(
x) ?
y :
x;
2509static bool is_quiet(
float x) {
2511 return (bit_cast<uint32_t>(
x) & (
static_cast<uint32_t
>(1) << 22)) != 0;
2514static uintx_t fclass(
float x) {
2515 ASSERT(!is_quiet(std::numeric_limits<float>::signaling_NaN()));
2516 ASSERT(is_quiet(std::numeric_limits<float>::quiet_NaN()));
2518 switch (fpclassify(
x)) {
2535static bool is_quiet(
double x) {
2537 return (bit_cast<uint64_t>(
x) & (
static_cast<uint64_t
>(1) << 51)) != 0;
2540static uintx_t fclass(
double x) {
2541 ASSERT(!is_quiet(std::numeric_limits<double>::signaling_NaN()));
2542 ASSERT(is_quiet(std::numeric_limits<double>::quiet_NaN()));
2544 switch (fpclassify(
x)) {
2561static float roundevenf(
float x) {
2562 float rounded = roundf(
x);
2563 if (fabsf(
x - rounded) == 0.5f) {
2564 if (fmodf(rounded, 2) != 0) {
2565 if (rounded > 0.0f) {
2570 ASSERT(fmodf(rounded, 2) == 0);
2576static double roundeven(
double x) {
2577 double rounded =
round(
x);
2578 if (fabs(
x - rounded) == 0.5f) {
2579 if (fmod(rounded, 2) != 0) {
2580 if (rounded > 0.0f) {
2585 ASSERT(fmod(rounded, 2) == 0);
2594 return roundevenf(
x);
2606 FATAL(
"Invalid rounding mode");
2613 return roundeven(
x);
2625 FATAL(
"Invalid rounding mode");
2634 return static_cast<int32_t
>(Round(
x, rounding));
2640 if (
x <
static_cast<float>(0)) {
2644 return static_cast<uint32_t
>(Round(
x, rounding));
2655 return static_cast<int64_t
>(Round(
x, rounding));
2661 if (
x <
static_cast<float>(0.0)) {
2665 return static_cast<uint64_t
>(Round(
x, rounding));
2676 return static_cast<int32_t
>(Round(
x, rounding));
2682 if (
x <
static_cast<double>(0)) {
2686 return static_cast<uint32_t
>(Round(
x, rounding));
2697 return static_cast<int64_t
>(Round(
x, rounding));
2703 if (
x <
static_cast<double>(0.0)) {
2707 return static_cast<uint64_t
>(Round(
x, rounding));
2713void Simulator::InterpretOPFP(Instr instr) {
2714 switch (instr.funct7()) {
2716 float rs1 = get_fregs(instr.frs1());
2717 float rs2 = get_fregs(instr.frs2());
2718 set_fregs(instr.frd(), rs1 + rs2);
2722 float rs1 = get_fregs(instr.frs1());
2723 float rs2 = get_fregs(instr.frs2());
2724 set_fregs(instr.frd(), rs1 - rs2);
2728 float rs1 = get_fregs(instr.frs1());
2729 float rs2 = get_fregs(instr.frs2());
2730 set_fregs(instr.frd(), rs1 * rs2);
2734 float rs1 = get_fregs(instr.frs1());
2735 float rs2 = get_fregs(instr.frs2());
2736 set_fregs(instr.frd(), rs1 / rs2);
2740 float rs1 = get_fregs(instr.frs1());
2741 set_fregs(instr.frd(), sqrtf(rs1));
2745 const uint32_t kSignMask =
static_cast<uint32_t
>(1) << 31;
2746 uint32_t rs1 = bit_cast<uint32_t>(get_fregs(instr.frs1()));
2747 uint32_t rs2 = bit_cast<uint32_t>(get_fregs(instr.frs2()));
2749 switch (instr.funct3()) {
2751 result = (rs1 & ~kSignMask) | (rs2 & kSignMask);
2754 result = (rs1 & ~kSignMask) | (~rs2 & kSignMask);
2757 result = (rs1 & ~kSignMask) | ((rs1 ^ rs2) & kSignMask);
2760 IllegalInstruction(instr);
2762 set_fregs(instr.frd(), bit_cast<float>(
result));
2766 float rs1 = get_fregs(instr.frs1());
2767 float rs2 = get_fregs(instr.frs2());
2768 switch (instr.funct3()) {
2770 set_fregs(instr.frd(), rv_fminf(rs1, rs2));
2773 set_fregs(instr.frd(), rv_fmaxf(rs1, rs2));
2776 IllegalInstruction(instr);
2781 float rs1 = get_fregs(instr.frs1());
2782 float rs2 = get_fregs(instr.frs2());
2783 switch (instr.funct3()) {
2785 set_xreg(instr.rd(), rs1 == rs2 ? 1 : 0);
2788 set_xreg(instr.rd(), rs1 < rs2 ? 1 : 0);
2791 set_xreg(instr.rd(), rs1 <= rs2 ? 1 : 0);
2794 IllegalInstruction(instr);
2799 switch (instr.funct3()) {
2802 set_xreg(instr.rd(), fclass(get_fregs(instr.frs1())));
2806 set_xreg(instr.rd(),
2807 sign_extend(bit_cast<int32_t>(get_fregs(instr.frs1()))));
2810 IllegalInstruction(instr);
2814 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2816 set_xreg(instr.rd(),
sign_extend(fcvtws(get_fregs(instr.frs1()),
2817 instr.rounding())));
2820 set_xreg(instr.rd(),
sign_extend(fcvtwus(get_fregs(instr.frs1()),
2821 instr.rounding())));
2825 set_xreg(instr.rd(),
sign_extend(fcvtls(get_fregs(instr.frs1()),
2826 instr.rounding())));
2829 set_xreg(instr.rd(),
sign_extend(fcvtlus(get_fregs(instr.frs1()),
2830 instr.rounding())));
2834 IllegalInstruction(instr);
2838 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2842 static_cast<float>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
2847 static_cast<float>(
static_cast<uint32_t
>(get_xreg(instr.rs1()))));
2853 static_cast<float>(
static_cast<int64_t
>(get_xreg(instr.rs1()))));
2858 static_cast<float>(
static_cast<uint64_t
>(get_xreg(instr.rs1()))));
2862 IllegalInstruction(instr);
2866 set_fregs(instr.frd(),
2867 bit_cast<float>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
2870 double rs1 = get_fregd(instr.frs1());
2871 double rs2 = get_fregd(instr.frs2());
2872 set_fregd(instr.frd(), rs1 + rs2);
2876 double rs1 = get_fregd(instr.frs1());
2877 double rs2 = get_fregd(instr.frs2());
2878 set_fregd(instr.frd(), rs1 - rs2);
2882 double rs1 = get_fregd(instr.frs1());
2883 double rs2 = get_fregd(instr.frs2());
2884 set_fregd(instr.frd(), rs1 * rs2);
2888 double rs1 = get_fregd(instr.frs1());
2889 double rs2 = get_fregd(instr.frs2());
2890 set_fregd(instr.frd(), rs1 / rs2);
2894 double rs1 = get_fregd(instr.frs1());
2895 set_fregd(instr.frd(),
sqrt(rs1));
2899 const uint64_t kSignMask =
static_cast<uint64_t
>(1) << 63;
2900 uint64_t rs1 = bit_cast<uint64_t>(get_fregd(instr.frs1()));
2901 uint64_t rs2 = bit_cast<uint64_t>(get_fregd(instr.frs2()));
2903 switch (instr.funct3()) {
2905 result = (rs1 & ~kSignMask) | (rs2 & kSignMask);
2908 result = (rs1 & ~kSignMask) | (~rs2 & kSignMask);
2911 result = (rs1 & ~kSignMask) | ((rs1 ^ rs2) & kSignMask);
2914 IllegalInstruction(instr);
2916 set_fregd(instr.frd(), bit_cast<double>(
result));
2920 double rs1 = get_fregd(instr.frs1());
2921 double rs2 = get_fregd(instr.frs2());
2922 switch (instr.funct3()) {
2924 set_fregd(instr.frd(), rv_fmin(rs1, rs2));
2927 set_fregd(instr.frd(), rv_fmax(rs1, rs2));
2930 IllegalInstruction(instr);
2935 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2937 set_fregs(instr.frd(),
static_cast<float>(get_fregd(instr.frs1())));
2940 IllegalInstruction(instr);
2945 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2947 set_fregd(instr.frd(),
static_cast<double>(get_fregs(instr.frs1())));
2950 IllegalInstruction(instr);
2956 double rs1 = get_fregd(instr.frs1());
2957 double rs2 = get_fregd(instr.frs2());
2958 switch (instr.funct3()) {
2960 set_xreg(instr.rd(), rs1 == rs2 ? 1 : 0);
2963 set_xreg(instr.rd(), rs1 < rs2 ? 1 : 0);
2966 set_xreg(instr.rd(), rs1 <= rs2 ? 1 : 0);
2969 IllegalInstruction(instr);
2974 switch (instr.funct3()) {
2977 set_xreg(instr.rd(), fclass(get_fregd(instr.frs1())));
2982 set_xreg(instr.rd(), bit_cast<int64_t>(get_fregd(instr.frs1())));
2986 IllegalInstruction(instr);
2990 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2992 set_xreg(instr.rd(),
sign_extend(fcvtwd(get_fregd(instr.frs1()),
2993 instr.rounding())));
2996 set_xreg(instr.rd(),
sign_extend(fcvtwud(get_fregd(instr.frs1()),
2997 instr.rounding())));
3001 set_xreg(instr.rd(),
sign_extend(fcvtld(get_fregd(instr.frs1()),
3002 instr.rounding())));
3005 set_xreg(instr.rd(),
sign_extend(fcvtlud(get_fregd(instr.frs1()),
3006 instr.rounding())));
3010 IllegalInstruction(instr);
3014 switch (
static_cast<FcvtRs2>(instr.rs2())) {
3018 static_cast<double>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
3021 set_fregd(instr.frd(),
static_cast<double>(
static_cast<uint32_t
>(
3022 get_xreg(instr.rs1()))));
3028 static_cast<double>(
static_cast<int64_t
>(get_xreg(instr.rs1()))));
3031 set_fregd(instr.frd(),
static_cast<double>(
static_cast<uint64_t
>(
3032 get_xreg(instr.rs1()))));
3036 IllegalInstruction(instr);
3041 set_fregd(instr.frd(), bit_cast<double>(get_xreg(instr.rs1())));
3045 IllegalInstruction(instr);
3047 pc_ += instr.length();
3050void Simulator::InterpretEBREAK(Instr instr) {
3053 FATAL(
"Encountered EBREAK");
3056void Simulator::InterpretEBREAK(CInstr instr) {
3059 FATAL(
"Encountered EBREAK");
3062void Simulator::IllegalInstruction(Instr instr) {
3065 FATAL(
"Illegal instruction: 0x%08x", instr.encoding());
3068void Simulator::IllegalInstruction(CInstr instr) {
3071 FATAL(
"Illegal instruction: 0x%04x", instr.encoding());
3074template <
typename type>
3078 if ((
addr +
sizeof(
type) > stack_base()) || (
addr < get_xreg(
SP))) {
3081 FATAL(
"Out-of-bounds stack access");
3088 FATAL(
"Bad memory access");
3095template <
typename type>
3099 if ((
addr +
sizeof(
type) > stack_base()) || (
addr < get_xreg(
SP))) {
3102 FATAL(
"Out-of-bounds stack access");
3109 FATAL(
"Bad memory access");
3116enum ControlStatusRegister {
3130intx_t Simulator::CSRRead(uint16_t csr) {
3135 return instret_ / 2;
3142 return (instret_ / 2) >> 32;
3146 return instret_ >> 32;
3149 FATAL(
"Unknown CSR: %d", csr);
3153void Simulator::CSRWrite(uint16_t csr, intx_t
value) {
3157void Simulator::CSRSet(uint16_t csr, intx_t mask) {
3161void Simulator::CSRClear(uint16_t csr, intx_t mask) {
static void round(SkPoint *p)
#define RA(width, name,...)
static Isolate * Current()
static uword RedirectExternalReference(uword function, CallKind call_kind, int argument_count)
static Simulator * Current()
static uword FunctionForRedirect(uword redirect)
#define THR_Print(format,...)
struct _Dart_NativeArguments * Dart_NativeArguments
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
const GrXPFactory * Get(SkBlendMode mode)
def link(from_root, to_root)
constexpr int64_t kMaxInt64
constexpr int64_t kMinInt64
const RegList kAbiVolatileCpuRegs
bool IsCInstruction(uint16_t parcel)
constexpr int32_t kMinInt32
const char *const fpu_reg_names[kNumberOfFpuRegisters]
constexpr uint64_t kMaxUint64
constexpr uint32_t kMaxUint32
const Register DISPATCH_TABLE_REG
const int kNumberOfFpuRegisters
const RegList kAbiPreservedCpuRegs
intx_t sign_extend(int32_t x)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
static T LoadUnaligned(const T *ptr)
static void StoreUnaligned(T *ptr, T value)
static constexpr int kPcMarkerSlotFromFp
const char *const cpu_reg_names[kNumberOfCpuRegisters]
constexpr int32_t kMaxInt32
constexpr Register WRITE_BARRIER_STATE
constexpr intptr_t kWordSize
const RegList kAbiVolatileFpuRegs
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
SIN Vec< N, float > trunc(const Vec< N, float > &x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
SIN Vec< N, float > floor(const Vec< N, float > &x)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
static double time(int loops, Benchmark *bench, Target *target)
int compare(const void *untyped_lhs, const void *untyped_rhs)
#define NO_SANITIZE_UNDEFINED(check)
#define OFFSET_OF(type, field)