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_; }
87 Simulator::CallKind call_kind()
const {
return call_kind_; }
91 static Redirection*
Get(uword external_function,
92 Simulator::CallKind call_kind,
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,
137 Simulator::CallKind call_kind,
139 : external_function_(external_function),
140 call_kind_(call_kind),
142 ecall_instruction_(Instr::kSimulatorRedirectInstruction),
145 uword external_function_;
146 Simulator::CallKind call_kind_;
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];
241 if ((kAbiVolatileCpuRegs & (1 << i)) != 0) {
242 xregs_[i] = random_.NextUInt64();
246 preserved->fregs[i] = fregs_[i];
247 if ((kAbiVolatileFpuRegs & (1 << i)) != 0) {
252 fregs_[i] = bit_cast<double>(kNaNBox);
258void Simulator::ClobberVolatileRegisters() {
260 reserved_address_ = reserved_value_ = 0;
262 if ((kAbiVolatileCpuRegs & (1 << i)) != 0) {
263 xregs_[i] = random_.NextUInt64();
267 if ((kAbiVolatileFpuRegs & (1 << i)) != 0) {
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]) {
301 FATAL(
"%s was not preserved\n", cpu_reg_names[i]);
306 if ((kAbiVolatileFpuRegs & (1 << i)) == 0) {
307 if (bit_cast<uint64_t>(preserved->fregs[i]) !=
308 bit_cast<uint64_t>(fregs_[i])) {
309 FATAL(
"%s was not preserved\n", fpu_reg_names[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);
385void Simulator::Execute() {
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;
431void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
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);
461 *
reinterpret_cast<uintx_t*
>(
fp + kPcMarkerSlotFromFp *
kWordSize);
462 uintx_t pp = FLAG_precompiled_mode
463 ?
static_cast<uintx_t
>(thread->global_object_pool())
464 : *reinterpret_cast<uintx_t*>(
467 set_xreg(CODE_REG, code);
469 set_xreg(WRITE_BARRIER_STATE,
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) {
474 set_xreg(DISPATCH_TABLE_REG,
475 reinterpret_cast<uintx_t
>(thread->dispatch_table_array()));
481void Simulator::PrintRegisters() {
482 ASSERT(
static_cast<intptr_t
>(kNumberOfCpuRegisters) ==
483 static_cast<intptr_t
>(kNumberOfFpuRegisters));
486 OS::Print(
"%4s: %8x %11d", cpu_reg_names[i], xregs_[i], xregs_[i]);
488 OS::Print(
"%4s: %16" Px64 " %20" Pd64, cpu_reg_names[i], xregs_[i],
491 OS::Print(
" %4s: %lf\n", fpu_reg_names[i], fregs_[i]);
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)));
779 switch (instr.encoding() & C_MISCALU_MASK) {
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());
801 switch (instr.encoding() & C_RR_MASK) {
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) {
1491 }
else if (
b == -1 &&
a == kMinInt32) {
1498static uint32_t divuw(uint32_t
a, uint32_t
b) {
1506static int32_t remw(int32_t
a, int32_t
b) {
1509 }
else if (
b == -1 &&
a == kMinInt32) {
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()))));
2005 cpu_reg_names[instr.rs1()], obj.ToCString());
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 InterpretAMO32(instr);
2095 InterpretAMO64(instr);
2098 IllegalInstruction(instr);
2105template <
typename type>
2106void Simulator::InterpretLR(Instr instr) {
2107 uintx_t
addr = get_xreg(instr.rs1());
2108 if ((addr & (
sizeof(
type) - 1)) != 0) {
2109 FATAL(
"Misaligned atomic memory operation");
2111 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2112 reserved_address_ =
addr;
2113 reserved_value_ = atomic->load(instr.memory_order());
2114 set_xreg(instr.rd(), reserved_value_);
2117template <
typename type>
2118void Simulator::InterpretSC(Instr instr) {
2119 uintx_t
addr = get_xreg(instr.rs1());
2120 if ((addr & (
sizeof(
type) - 1)) != 0) {
2121 FATAL(
"Misaligned atomic memory operation");
2123 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2124 if (addr != reserved_address_) {
2125 set_xreg(instr.rd(), 1);
2128 type expected = reserved_value_;
2129 type desired = get_xreg(instr.rs2());
2131 atomic->compare_exchange_strong(expected, desired, instr.memory_order());
2132 set_xreg(instr.rd(), success ? 0 : 1);
2135template <
typename type>
2136void Simulator::InterpretAMOSWAP(Instr instr) {
2137 uintx_t
addr = get_xreg(instr.rs1());
2138 if ((addr & (
sizeof(
type) - 1)) != 0) {
2139 FATAL(
"Misaligned atomic memory operation");
2141 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2142 type desired = get_xreg(instr.rs2());
2143 type result = atomic->exchange(desired, instr.memory_order());
2147template <
typename type>
2148void Simulator::InterpretAMOADD(Instr instr) {
2149 uintx_t
addr = get_xreg(instr.rs1());
2150 if ((addr & (
sizeof(
type) - 1)) != 0) {
2151 FATAL(
"Misaligned atomic memory operation");
2153 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2154 type arg = get_xreg(instr.rs2());
2155 type result = atomic->fetch_add(arg, instr.memory_order());
2159template <
typename type>
2160void Simulator::InterpretAMOXOR(Instr instr) {
2161 uintx_t
addr = get_xreg(instr.rs1());
2162 if ((addr & (
sizeof(
type) - 1)) != 0) {
2163 FATAL(
"Misaligned atomic memory operation");
2165 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2166 type arg = get_xreg(instr.rs2());
2167 type result = atomic->fetch_xor(arg, instr.memory_order());
2171template <
typename type>
2172void Simulator::InterpretAMOAND(Instr instr) {
2173 uintx_t
addr = get_xreg(instr.rs1());
2174 if ((addr & (
sizeof(
type) - 1)) != 0) {
2175 FATAL(
"Misaligned atomic memory operation");
2177 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2178 type arg = get_xreg(instr.rs2());
2179 type result = atomic->fetch_and(arg, instr.memory_order());
2183template <
typename type>
2184void Simulator::InterpretAMOOR(Instr instr) {
2185 uintx_t
addr = get_xreg(instr.rs1());
2186 if ((addr & (
sizeof(
type) - 1)) != 0) {
2187 FATAL(
"Misaligned atomic memory operation");
2189 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2190 type arg = get_xreg(instr.rs2());
2191 type result = atomic->fetch_or(arg, instr.memory_order());
2195template <
typename type>
2196void Simulator::InterpretAMOMIN(Instr instr) {
2197 uintx_t
addr = get_xreg(instr.rs1());
2198 if ((addr & (
sizeof(
type) - 1)) != 0) {
2199 FATAL(
"Misaligned atomic memory operation");
2201 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2202 type expected = atomic->load(std::memory_order_relaxed);
2208 !atomic->compare_exchange_weak(expected, desired, instr.memory_order()));
2212template <
typename type>
2213void Simulator::InterpretAMOMAX(Instr instr) {
2214 uintx_t
addr = get_xreg(instr.rs1());
2215 if ((addr & (
sizeof(
type) - 1)) != 0) {
2216 FATAL(
"Misaligned atomic memory operation");
2218 std::atomic<type>* atomic =
reinterpret_cast<std::atomic<type>*
>(
addr);
2219 type expected = atomic->load(std::memory_order_relaxed);
2225 !atomic->compare_exchange_weak(expected, desired, instr.memory_order()));
2229void Simulator::InterpretAMO32(Instr instr) {
2230 switch (instr.funct5()) {
2232 InterpretLR<int32_t>(instr);
2235 InterpretSC<int32_t>(instr);
2238 InterpretAMOSWAP<int32_t>(instr);
2241 InterpretAMOADD<int32_t>(instr);
2244 InterpretAMOXOR<int32_t>(instr);
2247 InterpretAMOAND<int32_t>(instr);
2250 InterpretAMOOR<int32_t>(instr);
2253 InterpretAMOMIN<int32_t>(instr);
2256 InterpretAMOMAX<int32_t>(instr);
2259 InterpretAMOMIN<uint32_t>(instr);
2262 InterpretAMOMAX<uint32_t>(instr);
2265 IllegalInstruction(instr);
2267 pc_ += instr.length();
2270void Simulator::InterpretAMO64(Instr instr) {
2271 switch (instr.funct5()) {
2274 InterpretLR<int64_t>(instr);
2277 InterpretSC<int64_t>(instr);
2280 InterpretAMOSWAP<int64_t>(instr);
2283 InterpretAMOADD<int64_t>(instr);
2286 InterpretAMOXOR<int64_t>(instr);
2289 InterpretAMOAND<int64_t>(instr);
2292 InterpretAMOOR<int64_t>(instr);
2295 InterpretAMOMIN<int64_t>(instr);
2298 InterpretAMOMAX<int64_t>(instr);
2301 InterpretAMOMIN<uint64_t>(instr);
2304 InterpretAMOMAX<uint64_t>(instr);
2308 IllegalInstruction(instr);
2310 pc_ += instr.length();
2313void Simulator::InterpretFMADD(Instr instr) {
2314 switch (instr.funct2()) {
2316 float rs1 = get_fregs(instr.frs1());
2317 float rs2 = get_fregs(instr.frs2());
2318 float rs3 = get_fregs(instr.frs3());
2319 set_fregs(instr.frd(), (rs1 * rs2) + rs3);
2323 double rs1 = get_fregd(instr.frs1());
2324 double rs2 = get_fregd(instr.frs2());
2325 double rs3 = get_fregd(instr.frs3());
2326 set_fregd(instr.frd(), (rs1 * rs2) + rs3);
2330 IllegalInstruction(instr);
2332 pc_ += instr.length();
2335void Simulator::InterpretFMSUB(Instr instr) {
2336 switch (instr.funct2()) {
2338 float rs1 = get_fregs(instr.frs1());
2339 float rs2 = get_fregs(instr.frs2());
2340 float rs3 = get_fregs(instr.frs3());
2341 set_fregs(instr.frd(), (rs1 * rs2) - rs3);
2345 double rs1 = get_fregd(instr.frs1());
2346 double rs2 = get_fregd(instr.frs2());
2347 double rs3 = get_fregd(instr.frs3());
2348 set_fregd(instr.frd(), (rs1 * rs2) - rs3);
2352 IllegalInstruction(instr);
2354 pc_ += instr.length();
2357void Simulator::InterpretFNMSUB(Instr instr) {
2358 switch (instr.funct2()) {
2360 float rs1 = get_fregs(instr.frs1());
2361 float rs2 = get_fregs(instr.frs2());
2362 float rs3 = get_fregs(instr.frs3());
2363 set_fregs(instr.frd(), -(rs1 * rs2) + rs3);
2367 double rs1 = get_fregd(instr.frs1());
2368 double rs2 = get_fregd(instr.frs2());
2369 double rs3 = get_fregd(instr.frs3());
2370 set_fregd(instr.frd(), -(rs1 * rs2) + rs3);
2374 IllegalInstruction(instr);
2376 pc_ += instr.length();
2379void Simulator::InterpretFNMADD(Instr instr) {
2380 switch (instr.funct2()) {
2382 float rs1 = get_fregs(instr.frs1());
2383 float rs2 = get_fregs(instr.frs2());
2384 float rs3 = get_fregs(instr.frs3());
2385 set_fregs(instr.frd(), -(rs1 * rs2) - rs3);
2389 double rs1 = get_fregd(instr.frs1());
2390 double rs2 = get_fregd(instr.frs2());
2391 double rs3 = get_fregd(instr.frs3());
2392 set_fregd(instr.frd(), -(rs1 * rs2) - rs3);
2396 IllegalInstruction(instr);
2398 pc_ += instr.length();
2405static double rv_fmin(
double x,
double y) {
2406 if (isnan(
x) && isnan(
y))
return std::numeric_limits<double>::quiet_NaN();
2407 if (isnan(
x))
return y;
2408 if (isnan(
y))
return x;
2409 if (
x ==
y)
return signbit(
x) ?
x :
y;
2413static double rv_fmax(
double x,
double y) {
2414 if (isnan(
x) && isnan(
y))
return std::numeric_limits<double>::quiet_NaN();
2415 if (isnan(
x))
return y;
2416 if (isnan(
y))
return x;
2417 if (
x ==
y)
return signbit(
x) ?
y :
x;
2421static float rv_fminf(
float x,
float y) {
2422 if (isnan(
x) && isnan(
y))
return std::numeric_limits<float>::quiet_NaN();
2423 if (isnan(
x))
return y;
2424 if (isnan(
y))
return x;
2425 if (
x ==
y)
return signbit(
x) ?
x :
y;
2429static float rv_fmaxf(
float x,
float y) {
2430 if (isnan(
x) && isnan(
y))
return std::numeric_limits<float>::quiet_NaN();
2431 if (isnan(
x))
return y;
2432 if (isnan(
y))
return x;
2433 if (
x ==
y)
return signbit(
x) ?
y :
x;
2437static bool is_quiet(
float x) {
2439 return (bit_cast<uint32_t>(
x) & (
static_cast<uint32_t
>(1) << 22)) != 0;
2442static uintx_t fclass(
float x) {
2443 ASSERT(!is_quiet(std::numeric_limits<float>::signaling_NaN()));
2444 ASSERT(is_quiet(std::numeric_limits<float>::quiet_NaN()));
2446 switch (fpclassify(
x)) {
2463static bool is_quiet(
double x) {
2465 return (bit_cast<uint64_t>(
x) & (
static_cast<uint64_t
>(1) << 51)) != 0;
2468static uintx_t fclass(
double x) {
2469 ASSERT(!is_quiet(std::numeric_limits<double>::signaling_NaN()));
2470 ASSERT(is_quiet(std::numeric_limits<double>::quiet_NaN()));
2472 switch (fpclassify(
x)) {
2489static float roundevenf(
float x) {
2490 float rounded = roundf(
x);
2491 if (fabsf(
x - rounded) == 0.5f) {
2492 if (fmodf(rounded, 2) != 0) {
2493 if (rounded > 0.0f) {
2498 ASSERT(fmodf(rounded, 2) == 0);
2504static double roundeven(
double x) {
2505 double rounded =
round(
x);
2506 if (fabs(
x - rounded) == 0.5f) {
2507 if (fmod(rounded, 2) != 0) {
2508 if (rounded > 0.0f) {
2513 ASSERT(fmod(rounded, 2) == 0);
2519static float Round(
float x, RoundingMode rounding) {
2522 return roundevenf(
x);
2534 FATAL(
"Invalid rounding mode");
2538static double Round(
double x, RoundingMode rounding) {
2541 return roundeven(
x);
2553 FATAL(
"Invalid rounding mode");
2557static int32_t fcvtws(
float x, RoundingMode rounding) {
2558 if (
x <
static_cast<float>(kMinInt32)) {
2561 if (
x <
static_cast<float>(kMaxInt32)) {
2562 return static_cast<int32_t
>(Round(
x, rounding));
2567static uint32_t fcvtwus(
float x, RoundingMode rounding) {
2568 if (
x <
static_cast<float>(0)) {
2571 if (
x <
static_cast<float>(kMaxUint32)) {
2572 return static_cast<uint32_t
>(Round(
x, rounding));
2578static int64_t fcvtls(
float x, RoundingMode rounding) {
2579 if (
x <
static_cast<float>(kMinInt64)) {
2582 if (
x <
static_cast<float>(kMaxInt64)) {
2583 return static_cast<int64_t
>(Round(
x, rounding));
2588static uint64_t fcvtlus(
float x, RoundingMode rounding) {
2589 if (
x <
static_cast<float>(0.0)) {
2592 if (
x <
static_cast<float>(kMaxUint64)) {
2593 return static_cast<uint64_t
>(Round(
x, rounding));
2599static int32_t fcvtwd(
double x, RoundingMode rounding) {
2600 if (
x <
static_cast<double>(kMinInt32)) {
2603 if (
x <
static_cast<double>(kMaxInt32)) {
2604 return static_cast<int32_t
>(Round(
x, rounding));
2609static uint32_t fcvtwud(
double x, RoundingMode rounding) {
2610 if (
x <
static_cast<double>(0)) {
2613 if (
x <
static_cast<double>(kMaxUint32)) {
2614 return static_cast<uint32_t
>(Round(
x, rounding));
2620static int64_t fcvtld(
double x, RoundingMode rounding) {
2621 if (
x <
static_cast<double>(kMinInt64)) {
2624 if (
x <
static_cast<double>(kMaxInt64)) {
2625 return static_cast<int64_t
>(Round(
x, rounding));
2630static uint64_t fcvtlud(
double x, RoundingMode rounding) {
2631 if (
x <
static_cast<double>(0.0)) {
2634 if (
x <
static_cast<double>(kMaxUint64)) {
2635 return static_cast<uint64_t
>(Round(
x, rounding));
2641void Simulator::InterpretOPFP(Instr instr) {
2642 switch (instr.funct7()) {
2644 float rs1 = get_fregs(instr.frs1());
2645 float rs2 = get_fregs(instr.frs2());
2646 set_fregs(instr.frd(), rs1 + rs2);
2650 float rs1 = get_fregs(instr.frs1());
2651 float rs2 = get_fregs(instr.frs2());
2652 set_fregs(instr.frd(), rs1 - rs2);
2656 float rs1 = get_fregs(instr.frs1());
2657 float rs2 = get_fregs(instr.frs2());
2658 set_fregs(instr.frd(), rs1 * rs2);
2662 float rs1 = get_fregs(instr.frs1());
2663 float rs2 = get_fregs(instr.frs2());
2664 set_fregs(instr.frd(), rs1 / rs2);
2668 float rs1 = get_fregs(instr.frs1());
2669 set_fregs(instr.frd(), sqrtf(rs1));
2673 const uint32_t kSignMask =
static_cast<uint32_t
>(1) << 31;
2674 uint32_t rs1 = bit_cast<uint32_t>(get_fregs(instr.frs1()));
2675 uint32_t rs2 = bit_cast<uint32_t>(get_fregs(instr.frs2()));
2677 switch (instr.funct3()) {
2679 result = (rs1 & ~kSignMask) | (rs2 & kSignMask);
2682 result = (rs1 & ~kSignMask) | (~rs2 & kSignMask);
2685 result = (rs1 & ~kSignMask) | ((rs1 ^ rs2) & kSignMask);
2688 IllegalInstruction(instr);
2690 set_fregs(instr.frd(), bit_cast<float>(
result));
2694 float rs1 = get_fregs(instr.frs1());
2695 float rs2 = get_fregs(instr.frs2());
2696 switch (instr.funct3()) {
2698 set_fregs(instr.frd(), rv_fminf(rs1, rs2));
2701 set_fregs(instr.frd(), rv_fmaxf(rs1, rs2));
2704 IllegalInstruction(instr);
2709 float rs1 = get_fregs(instr.frs1());
2710 float rs2 = get_fregs(instr.frs2());
2711 switch (instr.funct3()) {
2713 set_xreg(instr.rd(), rs1 == rs2 ? 1 : 0);
2716 set_xreg(instr.rd(), rs1 < rs2 ? 1 : 0);
2719 set_xreg(instr.rd(), rs1 <= rs2 ? 1 : 0);
2722 IllegalInstruction(instr);
2727 switch (instr.funct3()) {
2730 set_xreg(instr.rd(), fclass(get_fregs(instr.frs1())));
2734 set_xreg(instr.rd(),
2735 sign_extend(bit_cast<int32_t>(get_fregs(instr.frs1()))));
2738 IllegalInstruction(instr);
2742 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2744 set_xreg(instr.rd(),
sign_extend(fcvtws(get_fregs(instr.frs1()),
2745 instr.rounding())));
2748 set_xreg(instr.rd(),
sign_extend(fcvtwus(get_fregs(instr.frs1()),
2749 instr.rounding())));
2753 set_xreg(instr.rd(),
sign_extend(fcvtls(get_fregs(instr.frs1()),
2754 instr.rounding())));
2757 set_xreg(instr.rd(),
sign_extend(fcvtlus(get_fregs(instr.frs1()),
2758 instr.rounding())));
2762 IllegalInstruction(instr);
2766 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2770 static_cast<float>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
2775 static_cast<float>(
static_cast<uint32_t
>(get_xreg(instr.rs1()))));
2781 static_cast<float>(
static_cast<int64_t
>(get_xreg(instr.rs1()))));
2786 static_cast<float>(
static_cast<uint64_t
>(get_xreg(instr.rs1()))));
2790 IllegalInstruction(instr);
2794 set_fregs(instr.frd(),
2795 bit_cast<float>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
2798 double rs1 = get_fregd(instr.frs1());
2799 double rs2 = get_fregd(instr.frs2());
2800 set_fregd(instr.frd(), rs1 + rs2);
2804 double rs1 = get_fregd(instr.frs1());
2805 double rs2 = get_fregd(instr.frs2());
2806 set_fregd(instr.frd(), rs1 - rs2);
2810 double rs1 = get_fregd(instr.frs1());
2811 double rs2 = get_fregd(instr.frs2());
2812 set_fregd(instr.frd(), rs1 * rs2);
2816 double rs1 = get_fregd(instr.frs1());
2817 double rs2 = get_fregd(instr.frs2());
2818 set_fregd(instr.frd(), rs1 / rs2);
2822 double rs1 = get_fregd(instr.frs1());
2823 set_fregd(instr.frd(),
sqrt(rs1));
2827 const uint64_t kSignMask =
static_cast<uint64_t
>(1) << 63;
2828 uint64_t rs1 = bit_cast<uint64_t>(get_fregd(instr.frs1()));
2829 uint64_t rs2 = bit_cast<uint64_t>(get_fregd(instr.frs2()));
2831 switch (instr.funct3()) {
2833 result = (rs1 & ~kSignMask) | (rs2 & kSignMask);
2836 result = (rs1 & ~kSignMask) | (~rs2 & kSignMask);
2839 result = (rs1 & ~kSignMask) | ((rs1 ^ rs2) & kSignMask);
2842 IllegalInstruction(instr);
2844 set_fregd(instr.frd(), bit_cast<double>(
result));
2848 double rs1 = get_fregd(instr.frs1());
2849 double rs2 = get_fregd(instr.frs2());
2850 switch (instr.funct3()) {
2852 set_fregd(instr.frd(), rv_fmin(rs1, rs2));
2855 set_fregd(instr.frd(), rv_fmax(rs1, rs2));
2858 IllegalInstruction(instr);
2863 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2865 set_fregs(instr.frd(),
static_cast<float>(get_fregd(instr.frs1())));
2868 IllegalInstruction(instr);
2873 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2875 set_fregd(instr.frd(),
static_cast<double>(get_fregs(instr.frs1())));
2878 IllegalInstruction(instr);
2884 double rs1 = get_fregd(instr.frs1());
2885 double rs2 = get_fregd(instr.frs2());
2886 switch (instr.funct3()) {
2888 set_xreg(instr.rd(), rs1 == rs2 ? 1 : 0);
2891 set_xreg(instr.rd(), rs1 < rs2 ? 1 : 0);
2894 set_xreg(instr.rd(), rs1 <= rs2 ? 1 : 0);
2897 IllegalInstruction(instr);
2902 switch (instr.funct3()) {
2905 set_xreg(instr.rd(), fclass(get_fregd(instr.frs1())));
2910 set_xreg(instr.rd(), bit_cast<int64_t>(get_fregd(instr.frs1())));
2914 IllegalInstruction(instr);
2918 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2920 set_xreg(instr.rd(),
sign_extend(fcvtwd(get_fregd(instr.frs1()),
2921 instr.rounding())));
2924 set_xreg(instr.rd(),
sign_extend(fcvtwud(get_fregd(instr.frs1()),
2925 instr.rounding())));
2929 set_xreg(instr.rd(),
sign_extend(fcvtld(get_fregd(instr.frs1()),
2930 instr.rounding())));
2933 set_xreg(instr.rd(),
sign_extend(fcvtlud(get_fregd(instr.frs1()),
2934 instr.rounding())));
2938 IllegalInstruction(instr);
2942 switch (
static_cast<FcvtRs2>(instr.rs2())) {
2946 static_cast<double>(
static_cast<int32_t
>(get_xreg(instr.rs1()))));
2949 set_fregd(instr.frd(),
static_cast<double>(
static_cast<uint32_t
>(
2950 get_xreg(instr.rs1()))));
2956 static_cast<double>(
static_cast<int64_t
>(get_xreg(instr.rs1()))));
2959 set_fregd(instr.frd(),
static_cast<double>(
static_cast<uint64_t
>(
2960 get_xreg(instr.rs1()))));
2964 IllegalInstruction(instr);
2969 set_fregd(instr.frd(), bit_cast<double>(get_xreg(instr.rs1())));
2973 IllegalInstruction(instr);
2975 pc_ += instr.length();
2978void Simulator::InterpretEBREAK(Instr instr) {
2981 FATAL(
"Encountered EBREAK");
2984void Simulator::InterpretEBREAK(CInstr instr) {
2987 FATAL(
"Encountered EBREAK");
2990void Simulator::IllegalInstruction(Instr instr) {
2993 FATAL(
"Illegal instruction: 0x%08x", instr.encoding());
2996void Simulator::IllegalInstruction(CInstr instr) {
2999 FATAL(
"Illegal instruction: 0x%04x", instr.encoding());
3002template <
typename type>
3003type Simulator::MemoryRead(uintx_t addr, Register
base) {
3005 if ((
base == SP) || (
base == FP)) {
3006 if ((addr +
sizeof(
type) > stack_base()) || (addr < get_xreg(SP))) {
3009 FATAL(
"Out-of-bounds stack access");
3013 if ((addr < kPageSize) || (addr +
sizeof(
type) >= ~kPageSize)) {
3016 FATAL(
"Bad memory access");
3020 return LoadUnaligned(
reinterpret_cast<type*
>(addr));
3023template <
typename type>
3024void Simulator::MemoryWrite(uintx_t addr,
type value, Register
base) {
3026 if ((
base == SP) || (
base == FP)) {
3027 if ((addr +
sizeof(
type) > stack_base()) || (addr < get_xreg(SP))) {
3030 FATAL(
"Out-of-bounds stack access");
3034 if ((addr < kPageSize) || (addr +
sizeof(
type) >= ~kPageSize)) {
3037 FATAL(
"Bad memory access");
3041 StoreUnaligned(
reinterpret_cast<type*
>(addr), value);
3044enum ControlStatusRegister {
3058intx_t Simulator::CSRRead(uint16_t csr) {
3063 return instret_ / 2;
3070 return (instret_ / 2) >> 32;
3074 return instret_ >> 32;
3077 FATAL(
"Unknown CSR: %d", csr);
3081void Simulator::CSRWrite(uint16_t csr, intx_t value) {
3085void Simulator::CSRSet(uint16_t csr, intx_t mask) {
3089void Simulator::CSRClear(uint16_t csr, intx_t mask) {
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
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)
static const uint8_t buffer[]
#define DEFINE_FLAG(type, name, default_value, comment)
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)
constexpr int64_t kMaxInt64
constexpr int64_t kMinInt64
bool IsCInstruction(uint16_t parcel)
constexpr int32_t kMinInt32
constexpr uint64_t kMaxUint64
constexpr uint32_t kMaxUint32
const int kNumberOfFpuRegisters
const RegList kAbiPreservedCpuRegs
intx_t sign_extend(int32_t x)
constexpr int32_t kMaxInt32
constexpr intptr_t kWordSize
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)
#define NO_SANITIZE_UNDEFINED(check)
#define OFFSET_OF(type, field)