EmulateInstructionARM.h revision af556564f80fd417a9158754f5e2ee692e183f6d
1//===-- 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
13#include "lldb/Core/EmulateInstruction.h"
14#include "lldb/Core/Error.h"
15
16namespace lldb_private {
17
18// 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
34    // LastInITBlock - Returns true if we're the last instruction inside an IT Block.
35    bool LastInITBlock();
36
37    // 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
45class EmulateInstructionARM : public EmulateInstruction
46{
47public:
48    typedef enum
49    {
50        eEncodingA1,
51        eEncodingA2,
52        eEncodingA3,
53        eEncodingA4,
54        eEncodingA5,
55        eEncodingT1,
56        eEncodingT2,
57        eEncodingT3,
58        eEncodingT4,
59        eEncodingT5
60    } ARMEncoding;
61
62
63    static void
64    Initialize ();
65
66    static void
67    Terminate ();
68
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
106    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),
125        m_arm_isa (0),
126        m_inst_mode (eModeInvalid),
127        m_inst_cpsr (0),
128        m_it_session ()
129    {
130    }
131
132
133    virtual bool
134    SetTargetTriple (const ConstString &triple);
135
136    virtual bool
137    ReadInstruction ();
138
139    virtual bool
140    EvaluateInstruction ();
141
142    uint32_t
143    ArchVersion();
144
145    bool
146    ConditionPassed ();
147
148    uint32_t
149    CurrentCond ();
150
151    // 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
157    bool
158    BranchWritePC(const Context &context, uint32_t addr);
159
160    bool
161    BXWritePC(Context &context, uint32_t addr, Register &reg);
162
163    bool
164    LoadWritePC(Context &context, uint32_t addr, Register &reg);
165
166    bool
167    ALUWritePC(Context &context, uint32_t addr, Register &reg);
168
169    Mode
170    CurrentInstrSet();
171
172    bool
173    SelectInstrSet(Mode arm_or_thumb);
174
175    bool
176    WriteBits32Unknown (int n);
177
178    bool
179    WriteBits32UnknownToMemory (lldb::addr_t address);
180
181    bool
182    UnalignedSupport();
183
184    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
194protected:
195
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
238    EmulateLDRRtPCRelative (ARMEncoding encoding);
239
240    bool
241    EmulateAddSPImmediate (ARMEncoding encoding);
242
243    bool
244    EmulateAddSPRm (ARMEncoding encoding);
245
246    bool
247    EmulateBLXImmediate (ARMEncoding encoding);
248
249    bool
250    EmulateBLXRm (ARMEncoding encoding);
251
252    bool
253    EmulateBXRm (ARMEncoding encoding);
254
255    bool
256    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
270    bool
271    EmulateVPOP (ARMEncoding encoding);
272
273    bool
274    EmulateSVC (ARMEncoding encoding);
275
276    bool
277    EmulateIT (ARMEncoding encoding);
278
279    bool
280    EmulateB (ARMEncoding encoding);
281
282    // CBNZ, CBZ
283    bool
284    EmulateCB (ARMEncoding encoding);
285
286    bool
287    EmulateAddRdnRm (ARMEncoding encoding);
288
289    // MOV (register)
290    bool
291    EmulateMovRdRm (ARMEncoding encoding);
292
293    // MOV (immediate)
294    bool
295    EmulateMovRdImm (ARMEncoding encoding);
296
297    // MVN (immediate)
298    bool
299    EmulateMvnRdImm (ARMEncoding encoding);
300
301    bool
302    EmulateCmpRnImm (ARMEncoding encoding);
303
304    bool
305    EmulateCmpRnRm (ARMEncoding encoding);
306
307    bool
308    EmulateLDM (ARMEncoding encoding);
309
310    bool
311    EmulateLDMDA (ARMEncoding encoding);
312
313    bool
314    EmulateLDMDB (ARMEncoding encoding);
315
316    bool
317    EmulateLDMIB (ARMEncoding encoding);
318
319    bool
320    EmulateLDRRtRnImm (ARMEncoding encoding);
321
322    bool
323    EmulateSTM (ARMEncoding encoding);
324
325    bool
326    EmulateSTMDA (ARMEncoding encoding);
327
328    bool
329    EmulateSTMDB (ARMEncoding encoding);
330
331    bool
332    EmulateSTMIB (ARMEncoding encoding);
333
334    uint32_t m_arm_isa;
335    Mode m_inst_mode;
336    uint32_t m_inst_cpsr;
337    uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
338    ITSession m_it_session;
339};
340
341}   // namespace lldb_private
342
343#endif  // lldb_EmulateInstructionARM_h_
344