| Index: runtime/vm/simulator_arm64.h
|
| ===================================================================
|
| --- runtime/vm/simulator_arm64.h (revision 0)
|
| +++ runtime/vm/simulator_arm64.h (revision 0)
|
| @@ -0,0 +1,160 @@
|
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +// Declares a Simulator for ARM64 instructions if we are not generating a native
|
| +// ARM64 binary. This Simulator allows us to run and debug ARM64 code generation
|
| +// on regular desktop machines.
|
| +// Dart calls into generated code by "calling" the InvokeDartCode stub,
|
| +// which will start execution in the Simulator or forwards to the real entry
|
| +// on a ARM64 HW platform.
|
| +
|
| +#ifndef VM_SIMULATOR_ARM64_H_
|
| +#define VM_SIMULATOR_ARM64_H_
|
| +
|
| +#ifndef VM_SIMULATOR_H_
|
| +#error Do not include simulator_arm64.h directly; use simulator.h.
|
| +#endif
|
| +
|
| +#include "vm/constants_arm64.h"
|
| +#include "vm/object.h"
|
| +
|
| +namespace dart {
|
| +
|
| +class Isolate;
|
| +
|
| +class Simulator {
|
| + public:
|
| + static const uword kSimulatorStackUnderflowSize = 64;
|
| +
|
| + Simulator();
|
| + ~Simulator();
|
| +
|
| + // The currently executing Simulator instance, which is associated to the
|
| + // current isolate
|
| + static Simulator* Current();
|
| +
|
| + // Accessors for register state.
|
| + void set_register(Register reg, int64_t value, R31Type r31t = R31IsUndef);
|
| + int64_t get_register(Register reg, R31Type r31t = R31IsUndef) const;
|
| + void set_wregister(Register reg, int32_t value, R31Type r31t = R31IsUndef);
|
| + int32_t get_wregister(Register reg, R31Type r31t = R31IsUndef) const;
|
| +
|
| + int64_t get_pc() const;
|
| + void set_pc(int64_t pc);
|
| +
|
| + // Accessor to the internal simulator stack top.
|
| + uword StackTop() const;
|
| +
|
| + // The isolate's top_exit_frame_info refers to a Dart frame in the simulator
|
| + // stack. The simulator's top_exit_frame_info refers to a C++ frame in the
|
| + // native stack.
|
| + uword top_exit_frame_info() const { return top_exit_frame_info_; }
|
| + void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; }
|
| +
|
| + // Call on program start.
|
| + static void InitOnce() {}
|
| +
|
| + // Dart generally calls into generated code with 5 parameters. This is a
|
| + // convenience function, which sets up the simulator state and grabs the
|
| + // result on return. The return value is R0. The parameters are placed in
|
| + // R0-3.
|
| + int64_t Call(int64_t entry,
|
| + int64_t parameter0,
|
| + int64_t parameter1,
|
| + int64_t parameter2,
|
| + int64_t parameter3);
|
| +
|
| + void Longjmp(uword pc,
|
| + uword sp,
|
| + uword fp,
|
| + RawObject* raw_exception,
|
| + RawObject* raw_stacktrace) {
|
| + UNIMPLEMENTED();
|
| + }
|
| +
|
| + private:
|
| + // Known bad pc value to ensure that the simulator does not execute
|
| + // without being properly setup.
|
| + static const uword kBadLR = -1;
|
| + // A pc value used to signal the simulator to stop execution. Generally
|
| + // the lr is set to this value on transition from native C code to
|
| + // simulated execution, so that the simulator can "return" to the native
|
| + // C code.
|
| + static const uword kEndSimulatingPC = -2;
|
| +
|
| + // CPU state.
|
| + int64_t registers_[kNumberOfCpuRegisters];
|
| + bool n_flag_;
|
| + bool z_flag_;
|
| + bool c_flag_;
|
| + bool v_flag_;
|
| +
|
| + // Simulator support.
|
| + int64_t pc_;
|
| + char* stack_;
|
| + bool pc_modified_;
|
| + intptr_t icount_;
|
| + static int64_t flag_stop_sim_at_;
|
| + uword top_exit_frame_info_;
|
| +
|
| + // Registered breakpoints.
|
| + Instr* break_pc_;
|
| + int64_t break_instr_;
|
| +
|
| + // Illegal memory access support.
|
| + static bool IsIllegalAddress(uword addr) {
|
| + return addr < 64*1024;
|
| + }
|
| + void HandleIllegalAccess(uword addr, Instr* instr);
|
| +
|
| + // Handles a legal instruction that the simulator does not implement.
|
| + void UnimplementedInstruction(Instr* instr);
|
| +
|
| + // Unsupported instructions use Format to print an error and stop execution.
|
| + void Format(Instr* instr, const char* format);
|
| +
|
| + // Helper functions to set the conditional flags in the architecture state.
|
| + void SetNZFlagsW(int32_t val);
|
| + bool CarryFromW(int32_t left, int32_t right);
|
| + bool BorrowFromW(int32_t left, int32_t right);
|
| + bool OverflowFromW(
|
| + int32_t alu_out, int32_t left, int32_t right, bool addition);
|
| +
|
| + void SetNZFlagsX(int64_t val);
|
| + bool CarryFromX(int64_t left, int64_t right);
|
| + bool BorrowFromX(int64_t left, int64_t right);
|
| + bool OverflowFromX(
|
| + int64_t alu_out, int64_t left, int64_t right, bool addition);
|
| +
|
| + void SetCFlag(bool val);
|
| + void SetVFlag(bool val);
|
| +
|
| + int64_t ShiftOperand(uint8_t reg_size,
|
| + int64_t value,
|
| + Shift shift_type,
|
| + uint8_t amount);
|
| +
|
| + int64_t ExtendOperand(uint8_t reg_size,
|
| + int64_t value,
|
| + Extend extend_type,
|
| + uint8_t amount);
|
| +
|
| + int64_t DecodeShiftExtendOperand(Instr* instr);
|
| +
|
| + // Decode instructions.
|
| + void InstructionDecode(Instr* instr);
|
| + #define DECODE_OP(op) \
|
| + void Decode##op(Instr* instr);
|
| + APPLY_OP_LIST(DECODE_OP)
|
| + #undef DECODE_OP
|
| +
|
| + // Executes ARM64 instructions until the PC reaches kEndSimulatingPC.
|
| + void Execute();
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Simulator);
|
| +};
|
| +
|
| +} // namespace dart
|
| +
|
| +#endif // VM_SIMULATOR_ARM64_H_
|
|
|