blob: 6a6105da6f97f1bc53e67d21e04639b27e5f53bb [file] [log] [blame]
Greg Clayton64c84432011-01-21 22:02:52 +00001//===-- lldb_EmulateInstructionARM.h ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef lldb_EmulateInstructionARM_h_
11#define lldb_EmulateInstructionARM_h_
12
Greg Clayton8482ded2011-02-01 00:04:43 +000013#include "lldb/Core/EmulateInstruction.h"
Greg Clayton31e2a382011-01-30 20:03:56 +000014#include "lldb/Core/Error.h"
15
Greg Clayton64c84432011-01-21 22:02:52 +000016namespace lldb_private {
17
Johnny Chen93070472011-02-04 23:02:47 +000018// ITSession - Keep track of the IT Block progression.
19class ITSession
20{
21public:
22 ITSession() : ITCounter(0), ITState(0) {}
23 ~ITSession() {}
24
25 // InitIT - Initializes ITCounter/ITState.
26 bool InitIT(unsigned short bits7_0);
27
28 // ITAdvance - Updates ITCounter/ITState as IT Block progresses.
29 void ITAdvance();
30
31 // InITBlock - Returns true if we're inside an IT Block.
32 bool InITBlock();
33
Johnny Chenc315f862011-02-05 00:46:10 +000034 // LastInITBlock - Returns true if we're the last instruction inside an IT Block.
35 bool LastInITBlock();
36
Johnny Chen93070472011-02-04 23:02:47 +000037 // GetCond - Gets condition bits for the current thumb instruction.
38 uint32_t GetCond();
39
40private:
41 uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
42 uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
43};
44
Greg Clayton64c84432011-01-21 22:02:52 +000045class EmulateInstructionARM : public EmulateInstruction
46{
47public:
Greg Clayton2b8e8b02011-02-01 00:49:32 +000048 typedef enum
49 {
50 eEncodingA1,
51 eEncodingA2,
52 eEncodingA3,
53 eEncodingA4,
54 eEncodingA5,
55 eEncodingT1,
56 eEncodingT2,
57 eEncodingT3,
58 eEncodingT4,
Greg Clayton17f5afe2011-02-05 02:56:16 +000059 eEncodingT5
Greg Clayton2b8e8b02011-02-01 00:49:32 +000060 } ARMEncoding;
61
62
63 static void
64 Initialize ();
65
66 static void
67 Terminate ();
Greg Clayton31e2a382011-01-30 20:03:56 +000068
69 virtual const char *
70 GetPluginName()
71 {
72 return "EmulateInstructionARM";
73 }
74
75 virtual const char *
76 GetShortPluginName()
77 {
78 return "lldb.emulate-instruction.arm";
79 }
80
81 virtual uint32_t
82 GetPluginVersion()
83 {
84 return 1;
85 }
86
87 virtual void
88 GetPluginCommandHelp (const char *command, Stream *strm)
89 {
90 }
91
92 virtual lldb_private::Error
93 ExecutePluginCommand (Args &command, Stream *strm)
94 {
95 Error error;
96 error.SetErrorString("no plug-in commands are supported");
97 return error;
98 }
99
100 virtual Log *
101 EnablePluginLogging (Stream *strm, Args &command)
102 {
103 return NULL;
104 }
105
Greg Clayton64c84432011-01-21 22:02:52 +0000106 enum Mode
107 {
108 eModeInvalid,
109 eModeARM,
110 eModeThumb
111 };
112
113 EmulateInstructionARM (void *baton,
114 ReadMemory read_mem_callback,
115 WriteMemory write_mem_callback,
116 ReadRegister read_reg_callback,
117 WriteRegister write_reg_callback) :
118 EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM
119 4, // Address size in byte
120 baton,
121 read_mem_callback,
122 write_mem_callback,
123 read_reg_callback,
124 write_reg_callback),
Greg Clayton31e2a382011-01-30 20:03:56 +0000125 m_arm_isa (0),
126 m_inst_mode (eModeInvalid),
Johnny Chenc315f862011-02-05 00:46:10 +0000127 m_inst_cpsr (0),
128 m_it_session ()
Greg Clayton64c84432011-01-21 22:02:52 +0000129 {
130 }
Greg Clayton31e2a382011-01-30 20:03:56 +0000131
132
133 virtual bool
Greg Clayton395fc332011-02-15 21:59:32 +0000134 SetArchitecture (const ArchSpec &arch);
Greg Clayton64c84432011-01-21 22:02:52 +0000135
136 virtual bool
137 ReadInstruction ();
138
139 virtual bool
140 EvaluateInstruction ();
141
Johnny Chenee9b1f72011-02-09 01:00:31 +0000142 uint32_t
143 ArchVersion();
144
Greg Clayton64c84432011-01-21 22:02:52 +0000145 bool
146 ConditionPassed ();
147
148 uint32_t
149 CurrentCond ();
150
Johnny Chen098ae2d2011-02-12 00:50:05 +0000151 // InITBlock - Returns true if we're in Thumb mode and inside an IT Block.
152 bool InITBlock();
153
154 // LastInITBlock - Returns true if we're in Thumb mode and the last instruction inside an IT Block.
155 bool LastInITBlock();
156
Johnny Chen9ee056b2011-02-08 00:06:35 +0000157 bool
158 BranchWritePC(const Context &context, uint32_t addr);
159
160 bool
Johnny Chen668b4512011-02-15 21:08:58 +0000161 BXWritePC(Context &context, uint32_t addr);
Johnny Chen9ee056b2011-02-08 00:06:35 +0000162
Johnny Chenee9b1f72011-02-09 01:00:31 +0000163 bool
Johnny Chen668b4512011-02-15 21:08:58 +0000164 LoadWritePC(Context &context, uint32_t addr);
Johnny Chenee9b1f72011-02-09 01:00:31 +0000165
Johnny Chen26863dc2011-02-09 23:43:29 +0000166 bool
Johnny Chen668b4512011-02-15 21:08:58 +0000167 ALUWritePC(Context &context, uint32_t addr);
Johnny Chen26863dc2011-02-09 23:43:29 +0000168
Johnny Chenee9b1f72011-02-09 01:00:31 +0000169 Mode
170 CurrentInstrSet();
171
172 bool
173 SelectInstrSet(Mode arm_or_thumb);
174
Johnny Chenef21b592011-02-10 01:52:38 +0000175 bool
Caroline Tice713c2662011-02-11 17:59:55 +0000176 WriteBits32Unknown (int n);
177
178 bool
Caroline Ticefa172202011-02-11 22:49:54 +0000179 WriteBits32UnknownToMemory (lldb::addr_t address);
180
181 bool
Johnny Chenef21b592011-02-10 01:52:38 +0000182 UnalignedSupport();
183
Johnny Chenbf6ad172011-02-11 01:29:53 +0000184 typedef struct
185 {
186 uint32_t result;
187 uint8_t carry_out;
188 uint8_t overflow;
189 } AddWithCarryResult;
190
191 AddWithCarryResult
192 AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in);
193
Greg Clayton64c84432011-01-21 22:02:52 +0000194protected:
Greg Clayton2b8e8b02011-02-01 00:49:32 +0000195
196 // Typedef for the callback function used during the emulation.
197 // Pass along (ARMEncoding)encoding as the callback data.
198 typedef enum
199 {
200 eSize16,
201 eSize32
202 } ARMInstrSize;
203
204 typedef struct
205 {
206 uint32_t mask;
207 uint32_t value;
208 uint32_t variants;
209 EmulateInstructionARM::ARMEncoding encoding;
210 ARMInstrSize size;
211 bool (EmulateInstructionARM::*callback) (EmulateInstructionARM::ARMEncoding encoding);
212 const char *name;
213 } ARMOpcode;
214
215
216 static ARMOpcode*
217 GetARMOpcodeForInstruction (const uint32_t opcode);
218
219 static ARMOpcode*
220 GetThumbOpcodeForInstruction (const uint32_t opcode);
221
222 bool
223 EmulatePush (ARMEncoding encoding);
224
225 bool
226 EmulatePop (ARMEncoding encoding);
227
228 bool
229 EmulateAddRdSPImmediate (ARMEncoding encoding);
230
231 bool
232 EmulateMovRdSP (ARMEncoding encoding);
233
234 bool
235 EmulateMovLowHigh (ARMEncoding encoding);
236
237 bool
Johnny Chenc9de9102011-02-11 19:12:30 +0000238 EmulateLDRRtPCRelative (ARMEncoding encoding);
Greg Clayton2b8e8b02011-02-01 00:49:32 +0000239
240 bool
241 EmulateAddSPImmediate (ARMEncoding encoding);
242
243 bool
244 EmulateAddSPRm (ARMEncoding encoding);
245
246 bool
Johnny Chen9b8d7832011-02-02 01:13:56 +0000247 EmulateBLXImmediate (ARMEncoding encoding);
248
249 bool
250 EmulateBLXRm (ARMEncoding encoding);
251
252 bool
Johnny Chenab3b3512011-02-12 00:10:51 +0000253 EmulateBXRm (ARMEncoding encoding);
254
255 bool
Greg Clayton2b8e8b02011-02-01 00:49:32 +0000256 EmulateSubR7IPImmediate (ARMEncoding encoding);
257
258 bool
259 EmulateSubIPSPImmediate (ARMEncoding encoding);
260
261 bool
262 EmulateSubSPImmdiate (ARMEncoding encoding);
263
264 bool
265 EmulateSTRRtSP (ARMEncoding encoding);
266
267 bool
268 EmulateVPUSH (ARMEncoding encoding);
269
Johnny Chen587a0a42011-02-01 18:35:28 +0000270 bool
271 EmulateVPOP (ARMEncoding encoding);
272
Johnny Chenb77be412011-02-04 00:40:18 +0000273 bool
274 EmulateSVC (ARMEncoding encoding);
275
Johnny Chenc315f862011-02-05 00:46:10 +0000276 bool
277 EmulateIT (ARMEncoding encoding);
278
Johnny Chen3b620b32011-02-07 20:11:47 +0000279 bool
280 EmulateB (ARMEncoding encoding);
Caroline Ticeb9f76c32011-02-08 22:24:38 +0000281
Johnny Chen53ebab72011-02-08 23:21:57 +0000282 // CBNZ, CBZ
283 bool
284 EmulateCB (ARMEncoding encoding);
285
Caroline Ticeb9f76c32011-02-08 22:24:38 +0000286 bool
Johnny Chen26863dc2011-02-09 23:43:29 +0000287 EmulateAddRdnRm (ARMEncoding encoding);
288
Johnny Chend4dc4442011-02-11 02:02:56 +0000289 // MOV (register)
290 bool
291 EmulateMovRdRm (ARMEncoding encoding);
292
Johnny Chen357c30f2011-02-14 22:04:25 +0000293 // MOV (immediate)
294 bool
295 EmulateMovRdImm (ARMEncoding encoding);
296
Johnny Chen28070c32011-02-12 01:27:26 +0000297 // MVN (immediate)
298 bool
299 EmulateMvnRdImm (ARMEncoding encoding);
300
Johnny Chend4dc4442011-02-11 02:02:56 +0000301 bool
302 EmulateCmpRnImm (ARMEncoding encoding);
303
Johnny Chen26863dc2011-02-09 23:43:29 +0000304 bool
Johnny Chene4a4d302011-02-11 21:53:58 +0000305 EmulateCmpRnRm (ARMEncoding encoding);
306
Johnny Chen82f16aa2011-02-15 20:10:55 +0000307 // A8.6.14 ASR (immediate)
308 bool
309 EmulateASRImm (ARMEncoding encoding);
310
Johnny Chene4a4d302011-02-11 21:53:58 +0000311 bool
Caroline Ticeb9f76c32011-02-08 22:24:38 +0000312 EmulateLDM (ARMEncoding encoding);
Caroline Tice0b29e242011-02-08 23:16:02 +0000313
Caroline Tice713c2662011-02-11 17:59:55 +0000314 bool
315 EmulateLDMDA (ARMEncoding encoding);
316
Caroline Tice0b29e242011-02-08 23:16:02 +0000317 bool
318 EmulateLDMDB (ARMEncoding encoding);
Caroline Tice85aab332011-02-08 23:56:10 +0000319
320 bool
321 EmulateLDMIB (ARMEncoding encoding);
Johnny Chen3b620b32011-02-07 20:11:47 +0000322
Johnny Chenef21b592011-02-10 01:52:38 +0000323 bool
324 EmulateLDRRtRnImm (ARMEncoding encoding);
325
Caroline Ticefa172202011-02-11 22:49:54 +0000326 bool
327 EmulateSTM (ARMEncoding encoding);
328
Caroline Tice1511f502011-02-15 00:19:42 +0000329 bool
330 EmulateSTMDA (ARMEncoding encoding);
331
Caroline Ticeb6f8d7e2011-02-15 18:10:01 +0000332 bool
333 EmulateSTMDB (ARMEncoding encoding);
334
Caroline Ticeaf556562011-02-15 18:42:15 +0000335 bool
336 EmulateSTMIB (ARMEncoding encoding);
337
Greg Clayton31e2a382011-01-30 20:03:56 +0000338 uint32_t m_arm_isa;
Greg Clayton64c84432011-01-21 22:02:52 +0000339 Mode m_inst_mode;
340 uint32_t m_inst_cpsr;
Johnny Chen558133b2011-02-09 23:59:17 +0000341 uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
Johnny Chenc315f862011-02-05 00:46:10 +0000342 ITSession m_it_session;
Greg Clayton64c84432011-01-21 22:02:52 +0000343};
344
345} // namespace lldb_private
346
347#endif // lldb_EmulateInstructionARM_h_