armstate.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
  2. Copyright (C) 1994 Advanced RISC Machines Ltd.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #pragma once
  15. #include <array>
  16. #include <unordered_map>
  17. #include "common/common_types.h"
  18. #include "core/arm/skyeye_common/arm_regformat.h"
  19. // Signal levels
  20. enum {
  21. LOW = 0,
  22. HIGH = 1,
  23. LOWHIGH = 1,
  24. HIGHLOW = 2
  25. };
  26. // Cache types
  27. enum {
  28. NONCACHE = 0,
  29. DATACACHE = 1,
  30. INSTCACHE = 2,
  31. };
  32. // ARM privilege modes
  33. enum PrivilegeMode {
  34. USER32MODE = 16,
  35. FIQ32MODE = 17,
  36. IRQ32MODE = 18,
  37. SVC32MODE = 19,
  38. ABORT32MODE = 23,
  39. UNDEF32MODE = 27,
  40. SYSTEM32MODE = 31
  41. };
  42. // ARM privilege mode register banks
  43. enum {
  44. USERBANK = 0,
  45. FIQBANK = 1,
  46. IRQBANK = 2,
  47. SVCBANK = 3,
  48. ABORTBANK = 4,
  49. UNDEFBANK = 5,
  50. DUMMYBANK = 6,
  51. SYSTEMBANK = 7
  52. };
  53. // Hardware vector addresses
  54. enum {
  55. ARMResetV = 0,
  56. ARMUndefinedInstrV = 4,
  57. ARMSWIV = 8,
  58. ARMPrefetchAbortV = 12,
  59. ARMDataAbortV = 16,
  60. ARMAddrExceptnV = 20,
  61. ARMIRQV = 24,
  62. ARMFIQV = 28,
  63. ARMErrorV = 32, // This is an offset, not an address!
  64. ARMul_ResetV = ARMResetV,
  65. ARMul_UndefinedInstrV = ARMUndefinedInstrV,
  66. ARMul_SWIV = ARMSWIV,
  67. ARMul_PrefetchAbortV = ARMPrefetchAbortV,
  68. ARMul_DataAbortV = ARMDataAbortV,
  69. ARMul_AddrExceptnV = ARMAddrExceptnV,
  70. ARMul_IRQV = ARMIRQV,
  71. ARMul_FIQV = ARMFIQV
  72. };
  73. // Coprocessor status values
  74. enum {
  75. ARMul_FIRST = 0,
  76. ARMul_TRANSFER = 1,
  77. ARMul_BUSY = 2,
  78. ARMul_DATA = 3,
  79. ARMul_INTERRUPT = 4,
  80. ARMul_DONE = 0,
  81. ARMul_CANT = 1,
  82. ARMul_INC = 3
  83. };
  84. // Instruction condition codes
  85. enum ConditionCode {
  86. EQ = 0,
  87. NE = 1,
  88. CS = 2,
  89. CC = 3,
  90. MI = 4,
  91. PL = 5,
  92. VS = 6,
  93. VC = 7,
  94. HI = 8,
  95. LS = 9,
  96. GE = 10,
  97. LT = 11,
  98. GT = 12,
  99. LE = 13,
  100. AL = 14,
  101. NV = 15,
  102. };
  103. // Flags for use with the APSR.
  104. enum : u32 {
  105. NBIT = (1U << 31U),
  106. ZBIT = (1 << 30),
  107. CBIT = (1 << 29),
  108. VBIT = (1 << 28),
  109. QBIT = (1 << 27),
  110. JBIT = (1 << 24),
  111. EBIT = (1 << 9),
  112. ABIT = (1 << 8),
  113. IBIT = (1 << 7),
  114. FBIT = (1 << 6),
  115. TBIT = (1 << 5),
  116. // Masks for groups of bits in the APSR.
  117. MODEBITS = 0x1F,
  118. INTBITS = 0x1C0,
  119. };
  120. // Values for Emulate.
  121. enum {
  122. STOP = 0, // Stop
  123. CHANGEMODE = 1, // Change mode
  124. ONCE = 2, // Execute just one iteration
  125. RUN = 3 // Continuous execution
  126. };
  127. struct ARMul_State final
  128. {
  129. public:
  130. explicit ARMul_State(PrivilegeMode initial_mode);
  131. void ChangePrivilegeMode(u32 new_mode);
  132. void Reset();
  133. // Reads/writes data in big/little endian format based on the
  134. // state of the E (endian) bit in the APSR.
  135. u8 ReadMemory8(u32 address) const;
  136. u16 ReadMemory16(u32 address) const;
  137. u32 ReadMemory32(u32 address) const;
  138. u64 ReadMemory64(u32 address) const;
  139. void WriteMemory8(u32 address, u8 data);
  140. void WriteMemory16(u32 address, u16 data);
  141. void WriteMemory32(u32 address, u32 data);
  142. void WriteMemory64(u32 address, u64 data);
  143. u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const;
  144. void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
  145. // Exclusive memory access functions
  146. bool IsExclusiveMemoryAccess(u32 address) const {
  147. return exclusive_state && exclusive_tag == (address & RESERVATION_GRANULE_MASK);
  148. }
  149. void SetExclusiveMemoryAddress(u32 address) {
  150. exclusive_tag = address & RESERVATION_GRANULE_MASK;
  151. exclusive_state = true;
  152. }
  153. void UnsetExclusiveMemoryAddress() {
  154. exclusive_tag = 0xFFFFFFFF;
  155. exclusive_state = false;
  156. }
  157. // Whether or not the given CPU is in big endian mode (E bit is set)
  158. bool InBigEndianMode() const {
  159. return (Cpsr & (1 << 9)) != 0;
  160. }
  161. // Whether or not the given CPU is in a mode other than user mode.
  162. bool InAPrivilegedMode() const {
  163. return (Mode != USER32MODE);
  164. }
  165. // Note that for the 3DS, a Thumb instruction will only ever be
  166. // two bytes in size. Thus we don't need to worry about ThumbEE
  167. // or Thumb-2 where instructions can be 4 bytes in length.
  168. u32 GetInstructionSize() const {
  169. return TFlag ? 2 : 4;
  170. }
  171. std::array<u32, 16> Reg; // The current register file
  172. std::array<u32, 2> Reg_usr;
  173. std::array<u32, 2> Reg_svc; // R13_SVC R14_SVC
  174. std::array<u32, 2> Reg_abort; // R13_ABORT R14_ABORT
  175. std::array<u32, 2> Reg_undef; // R13 UNDEF R14 UNDEF
  176. std::array<u32, 2> Reg_irq; // R13_IRQ R14_IRQ
  177. std::array<u32, 7> Reg_firq; // R8---R14 FIRQ
  178. std::array<u32, 7> Spsr; // The exception psr's
  179. std::array<u32, CP15_REGISTER_COUNT> CP15;
  180. // FPSID, FPSCR, and FPEXC
  181. std::array<u32, VFP_SYSTEM_REGISTER_COUNT> VFP;
  182. // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
  183. // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
  184. // and only 32 singleword registers are accessible (S0-S31).
  185. std::array<u32, 64> ExtReg;
  186. u32 Emulate; // To start and stop emulation
  187. u32 Cpsr; // The current PSR
  188. u32 Spsr_copy;
  189. u32 phys_pc;
  190. u32 Mode; // The current mode
  191. u32 Bank; // The current register bank
  192. u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
  193. unsigned int shifter_carry_out;
  194. u32 TFlag; // Thumb state
  195. unsigned long long NumInstrs; // The number of instructions executed
  196. unsigned NumInstrsToExecute;
  197. unsigned NresetSig; // Reset the processor
  198. unsigned NfiqSig;
  199. unsigned NirqSig;
  200. unsigned abortSig;
  201. unsigned NtransSig;
  202. unsigned bigendSig;
  203. unsigned syscallSig;
  204. // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
  205. // process for our purposes), not per ARMul_State (which tracks CPU core state).
  206. std::unordered_map<u32, int> instruction_cache;
  207. private:
  208. void ResetMPCoreCP15Registers();
  209. // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
  210. // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
  211. // support LDR/STREXD.
  212. static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
  213. u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
  214. bool exclusive_state;
  215. };