Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Unified Diff: runtime/vm/simulator_arm.h

Issue 12041056: Initial revision of ARM simulator and (empty) MIPS simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/simulator.h ('k') | runtime/vm/simulator_arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_arm.h
===================================================================
--- runtime/vm/simulator_arm.h (revision 0)
+++ runtime/vm/simulator_arm.h (revision 0)
@@ -0,0 +1,230 @@
+// Copyright (c) 2013, 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 ARM instructions if we are not generating a native
+// ARM binary. This Simulator allows us to run and debug ARM 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 ARM HW platform.
+
+#ifndef VM_SIMULATOR_ARM_H_
+#define VM_SIMULATOR_ARM_H_
+
+#ifndef VM_SIMULATOR_H_
+#error Do not include simulator_arm.h directly; use simulator.h.
+#endif
+
+#include "vm/allocation.h"
+#include "vm/constants_arm.h"
+#include "vm/object.h"
+
+namespace dart {
+
+class Isolate;
+class SimulatorSetjmpBuffer;
+
+class Simulator {
+ public:
+ static const size_t kSimulatorStackUnderflowSize = 64;
+
+ Simulator();
+ ~Simulator();
+
+ // The currently executing Simulator instance, which is associated to the
+ // current isolate
+ static Simulator* Current();
+
+ // Accessors for register state. Reading the pc value adheres to the ARM
+ // architecture specification and is off by 8 from the currently executing
+ // instruction.
+ void set_register(Register reg, int32_t value);
+ int32_t get_register(Register reg) const;
+
+ // Special case of set_register and get_register to access the raw PC value.
+ void set_pc(int32_t value);
+ int32_t get_pc() const;
+
+ // Accessors for VFP register state.
+ void set_sregister(SRegister reg, float value);
+ float get_sregister(SRegister reg) const;
+ void set_dregister(DRegister reg, double value);
+ double get_dregister(DRegister reg) const;
+
+ // Accessor to the internal simulator stack area.
+ uintptr_t StackTop() const;
+ uintptr_t StackLimit() const;
+
+ // Executes ARM instructions until the PC reaches end_sim_pc.
+ void Execute();
+
+ // 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.
+ int64_t Call(int32_t entry,
+ int32_t parameter0,
+ int32_t parameter1,
+ int32_t parameter2,
+ int32_t parameter3,
+ int32_t parameter4);
+
+ // Implementation of atomic compare and exchange in the same synchronization
+ // domain as other synchronization primitive instructions (e.g. ldrex, strex).
+ static uword CompareExchange(uword* address,
+ uword compare_value,
+ uword new_value);
+
+ // Runtime call support.
+ static uword RedirectExternalReference(void* function,
+ uint32_t argument_count);
+
+ void Longjmp(int32_t pc, int32_t sp, int32_t fp, const Instance& object);
+
+ 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.
+ int32_t registers_[kNumberOfCpuRegisters];
+ bool n_flag_;
+ bool z_flag_;
+ bool c_flag_;
+ bool v_flag_;
+
+ // VFP state.
+ union { // S and D register banks are overlapping.
+ float sregisters_[kNumberOfSRegisters];
+ double dregisters_[kNumberOfDRegisters];
+ };
+ bool fp_n_flag_;
+ bool fp_z_flag_;
+ bool fp_c_flag_;
+ bool fp_v_flag_;
+
+ // Simulator support.
+ char* stack_;
+ bool pc_modified_;
+ int icount_;
+ static bool flag_trace_sim_;
+ static int32_t flag_stop_sim_at_;
+ SimulatorSetjmpBuffer* last_setjmp_buffer_;
+
+ // Registered breakpoints.
+ Instr* break_pc_;
+ int32_t break_instr_;
+
+ // Illegal memory access support.
+ static bool IsIllegalAddress(uword addr) {
+ return addr < 64*1024;
+ }
+ void HandleIllegalAccess(uword addr, Instr* instr);
+
+ // Unsupported instructions use Format to print an error and stop execution.
+ void Format(Instr* instr, const char* format);
+
+ // Checks if the current instruction should be executed based on its
+ // condition bits.
+ bool ConditionallyExecute(Instr* instr);
+
+ // Helper functions to set the conditional flags in the architecture state.
+ void SetNZFlags(int32_t val);
+ void SetCFlag(bool val);
+ void SetVFlag(bool val);
+ bool CarryFrom(int32_t left, int32_t right);
+ bool BorrowFrom(int32_t left, int32_t right);
+ bool OverflowFrom(int32_t alu_out,
+ int32_t left,
+ int32_t right,
+ bool addition);
+
+ // Helper functions to decode common "addressing" modes.
+ int32_t GetShiftRm(Instr* instr, bool* carry_out);
+ int32_t GetImm(Instr* instr, bool* carry_out);
+ void HandleRList(Instr* instr, bool load);
+ void SupervisorCall(Instr* instr);
+
+ // Read and write memory.
+ void UnalignedAccess(const char* msg, uword addr, Instr* instr);
+
+ inline uint8_t ReadBU(uword addr);
+ inline int8_t ReadB(uword addr);
+ inline void WriteB(uword addr, uint8_t value);
+
+ inline uint16_t ReadHU(uword addr, Instr* instr);
+ inline int16_t ReadH(uword addr, Instr* instr);
+ inline void WriteH(uword addr, uint16_t value, Instr* instr);
+
+ inline int ReadW(uword addr, Instr* instr);
+ inline void WriteW(uword addr, int value, Instr* instr);
+
+ // Synchronization primitives support.
+ void ClearExclusive();
+ int ReadExclusiveW(uword addr, Instr* instr);
+ int WriteExclusiveW(uword addr, int value, Instr* instr);
+
+ // TODO(regis): Remove exclusive access support machinery if not needed.
+ // In Dart, there is at most one thread per isolate.
+ // We keep track of 16 exclusive access address tags across all isolates.
+ // Since we cannot simulate a native context switch, which clears
+ // the exclusive access state of the local monitor (using the CLREX
+ // instruction), we associate the isolate requesting exclusive access to the
+ // address tag. Multiple isolates requesting exclusive access (using the LDREX
+ // instruction) to the same address will result in multiple address tags being
+ // created for the same address, one per isolate.
+ // At any given time, each isolate is associated to at most one address tag.
+ static Mutex* exclusive_access_lock_;
+ static const int kNumAddressTags = 16;
+ static struct AddressTag {
+ Isolate* isolate;
+ uword addr;
+ } exclusive_access_state_[kNumAddressTags];
+ static int next_address_tag_;
+
+ // Set access to given address to 'exclusive state' for current isolate.
+ static void SetExclusiveAccess(uword addr);
+
+ // Returns true if the current isolate has exclusive access to given address,
+ // returns false otherwise. In either case, set access to given address to
+ // 'open state' for all isolates.
+ // If given addr is NULL, set access to 'open state' for current
+ // isolate (CLREX).
+ static bool HasExclusiveAccessAndOpen(uword addr);
+
+ // Executing is handled based on the instruction type.
+ void DecodeType01(Instr* instr); // Both type 0 and type 1 rolled into one.
+ void DecodeType2(Instr* instr);
+ void DecodeType3(Instr* instr);
+ void DecodeType4(Instr* instr);
+ void DecodeType5(Instr* instr);
+ void DecodeType6(Instr* instr);
+ void DecodeType7(Instr* instr);
+
+ // Executes one instruction.
+ void InstructionDecode(Instr* instr);
+
+ // Longjmp support for exceptions.
+ SimulatorSetjmpBuffer* last_setjmp_buffer() {
+ return last_setjmp_buffer_;
+ }
+ void set_last_setjmp_buffer(SimulatorSetjmpBuffer* buffer) {
+ last_setjmp_buffer_ = buffer;
+ }
+
+ friend class SimulatorDebugger;
+ friend class SimulatorSetjmpBuffer;
+ DISALLOW_COPY_AND_ASSIGN(Simulator);
+};
+
+} // namespace dart
+
+#endif // VM_SIMULATOR_ARM_H_
« no previous file with comments | « runtime/vm/simulator.h ('k') | runtime/vm/simulator_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698