]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
Merge ^/head r275715 through r275748.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / ABI / SysV-hexagon / ABISysV_hexagon.cpp
1 //===-- ABISysV_hexagon.cpp --------------------------------------*- 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 #include "ABISysV_hexagon.h"
11
12 #include "lldb/Core/ConstString.h"
13 #include "lldb/Core/DataExtractor.h"
14 #include "lldb/Core/Error.h"
15 #include "lldb/Core/Log.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/RegisterValue.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectConstResult.h"
21 #include "lldb/Core/ValueObjectRegister.h"
22 #include "lldb/Core/ValueObjectMemory.h"
23 #include "lldb/Symbol/ClangASTContext.h"
24 #include "lldb/Symbol/UnwindPlan.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/RegisterContext.h"
28 #include "lldb/Target/StackFrame.h"
29 #include "lldb/Target/Thread.h"
30
31 #include "llvm/ADT/Triple.h"
32
33 #include "llvm/IR/Type.h"
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 static RegisterInfo g_register_infos[] = 
39 {
40     // hexagon-core.xml
41     { "r00"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  0,  0, LLDB_INVALID_REGNUM,     0,  0 }, NULL, NULL },
42     { "r01"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  1,  1, LLDB_INVALID_REGNUM,     1,  1 }, NULL, NULL },
43     { "r02"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  2,  2, LLDB_INVALID_REGNUM,     2,  2 }, NULL, NULL },
44     { "r03"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  3,  3, LLDB_INVALID_REGNUM,     3,  3 }, NULL, NULL },
45     { "r04"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  4,  4, LLDB_INVALID_REGNUM,     4,  4 }, NULL, NULL },
46     { "r05"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  5,  5, LLDB_INVALID_REGNUM,     5,  5 }, NULL, NULL },
47     { "r06"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  6,  6, LLDB_INVALID_REGNUM,     6,  6 }, NULL, NULL },
48     { "r07"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  7,  7, LLDB_INVALID_REGNUM,     7,  7 }, NULL, NULL },
49     { "r08"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  8,  8, LLDB_INVALID_REGNUM,     8,  8 }, NULL, NULL },
50     { "r09"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, {  9,  9, LLDB_INVALID_REGNUM,     9,  9 }, NULL, NULL },
51     { "r10"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 10, 10, LLDB_INVALID_REGNUM,    10, 10 }, NULL, NULL },
52     { "r11"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 11, 11, LLDB_INVALID_REGNUM,    11, 11 }, NULL, NULL },
53     { "r12"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 12, 12, LLDB_INVALID_REGNUM,    12, 12 }, NULL, NULL },
54     { "r13"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 13, 13, LLDB_INVALID_REGNUM,    13, 13 }, NULL, NULL },
55     { "r14"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 14, 14, LLDB_INVALID_REGNUM,    14, 14 }, NULL, NULL },
56     { "r15"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 15, 15, LLDB_INVALID_REGNUM,    15, 15 }, NULL, NULL },
57     { "r16"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 16, 16, LLDB_INVALID_REGNUM,    16, 16 }, NULL, NULL },
58     { "r17"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 17, 17, LLDB_INVALID_REGNUM,    17, 17 }, NULL, NULL },
59     { "r18"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 18, 18, LLDB_INVALID_REGNUM,    18, 18 }, NULL, NULL },
60     { "r19"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 19, 19, LLDB_INVALID_REGNUM,    19, 19 }, NULL, NULL },
61     { "r20"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 20, 20, LLDB_INVALID_REGNUM,    20, 20 }, NULL, NULL },
62     { "r21"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 21, 21, LLDB_INVALID_REGNUM,    21, 21 }, NULL, NULL },
63     { "r22"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 22, 22, LLDB_INVALID_REGNUM,    22, 22 }, NULL, NULL },
64     { "r23"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 23, 23, LLDB_INVALID_REGNUM,    23, 23 }, NULL, NULL },
65     { "r24"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 24, 24, LLDB_INVALID_REGNUM,    24, 24 }, NULL, NULL },
66     { "r25"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 25, 25, LLDB_INVALID_REGNUM,    25, 25 }, NULL, NULL },
67     { "r26"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 26, 26, LLDB_INVALID_REGNUM,    26, 26 }, NULL, NULL },
68     { "r27"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 27, 27, LLDB_INVALID_REGNUM,    27, 27 }, NULL, NULL },
69     { "r28"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 28, 28, LLDB_INVALID_REGNUM,    28, 28 }, NULL, NULL },
70     { "sp"  ,"r29", 4, 0, eEncodingUint, eFormatAddressInfo, { 29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29 }, NULL, NULL },
71     { "fp"  ,"r30", 4, 0, eEncodingUint, eFormatAddressInfo, { 30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30 }, NULL, NULL },
72     { "lr"  ,"r31", 4, 0, eEncodingUint, eFormatAddressInfo, { 31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31 }, NULL, NULL },
73     { "sa0"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 32, 32, LLDB_INVALID_REGNUM,    32, 32 }, NULL, NULL },
74     { "lc0"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 33, 33, LLDB_INVALID_REGNUM,    33, 33 }, NULL, NULL },
75     { "sa1"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 34, 34, LLDB_INVALID_REGNUM,    34, 34 }, NULL, NULL },
76     { "lc1"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 35, 35, LLDB_INVALID_REGNUM,    35, 35 }, NULL, NULL },
77     // --> hexagon-v4/5/55/56-sim.xml
78     { "p3_0"  , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 36, 36, LLDB_INVALID_REGNUM,    36, 36 }, NULL, NULL },
79 // PADDING {
80     { "p00"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 37, 37, LLDB_INVALID_REGNUM,    37, 37 }, NULL, NULL },
81 // }
82     { "m0"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 38, 38, LLDB_INVALID_REGNUM,    38, 38 }, NULL, NULL },
83     { "m1"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 39, 39, LLDB_INVALID_REGNUM,    39, 39 }, NULL, NULL },
84     { "usr"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 40, 40, LLDB_INVALID_REGNUM,    40, 40 }, NULL, NULL },
85     { "pc"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41 }, NULL, NULL },
86     { "ugp"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 42, 42, LLDB_INVALID_REGNUM,    42, 42 }, NULL, NULL },
87     { "gp"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 43, 43, LLDB_INVALID_REGNUM,    43, 43 }, NULL, NULL },
88     { "cs0"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 44, 44, LLDB_INVALID_REGNUM,    44, 44 }, NULL, NULL },
89     { "cs1"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 45, 45, LLDB_INVALID_REGNUM,    45, 45 }, NULL, NULL },
90 // PADDING {
91     { "p01"   , "", 4, 0, eEncodingInvalid, eFormatInvalid,     { 46, 46, LLDB_INVALID_REGNUM,    46, 46 }, NULL, NULL },
92     { "p02"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 47, 47, LLDB_INVALID_REGNUM,    47, 47 }, NULL, NULL },
93     { "p03"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 48, 48, LLDB_INVALID_REGNUM,    48, 48 }, NULL, NULL },
94     { "p04"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 49, 49, LLDB_INVALID_REGNUM,    49, 49 }, NULL, NULL },
95     { "p05"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 50, 50, LLDB_INVALID_REGNUM,    50, 50 }, NULL, NULL },
96     { "p06"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 51, 51, LLDB_INVALID_REGNUM,    51, 51 }, NULL, NULL },
97     { "p07"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 52, 52, LLDB_INVALID_REGNUM,    52, 52 }, NULL, NULL },
98     { "p08"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 53, 53, LLDB_INVALID_REGNUM,    53, 53 }, NULL, NULL },
99     { "p09"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 54, 54, LLDB_INVALID_REGNUM,    54, 54 }, NULL, NULL },
100     { "p10"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 55, 55, LLDB_INVALID_REGNUM,    55, 55 }, NULL, NULL },
101     { "p11"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 56, 56, LLDB_INVALID_REGNUM,    56, 56 }, NULL, NULL },
102     { "p12"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 57, 57, LLDB_INVALID_REGNUM,    57, 57 }, NULL, NULL },
103     { "p13"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 58, 58, LLDB_INVALID_REGNUM,    58, 58 }, NULL, NULL },
104     { "p14"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 59, 59, LLDB_INVALID_REGNUM,    59, 59 }, NULL, NULL },
105     { "p15"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 60, 60, LLDB_INVALID_REGNUM,    60, 60 }, NULL, NULL },
106     { "p16"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 61, 61, LLDB_INVALID_REGNUM,    61, 61 }, NULL, NULL },
107     { "p17"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 62, 62, LLDB_INVALID_REGNUM,    62, 62 }, NULL, NULL },
108     { "p18"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 63, 63, LLDB_INVALID_REGNUM,    63, 63 }, NULL, NULL },
109 // }
110     { "sgp0"  , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 64, 64, LLDB_INVALID_REGNUM,    64, 64 }, NULL, NULL },
111 // PADDING {
112     { "p19"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 65, 65, LLDB_INVALID_REGNUM,    65, 65 }, NULL, NULL },
113 // }
114     { "stid"  , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 66, 66, LLDB_INVALID_REGNUM,    66, 66 }, NULL, NULL },
115     { "elr"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 67, 67, LLDB_INVALID_REGNUM,    67, 67 }, NULL, NULL },
116     { "badva0", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 68, 68, LLDB_INVALID_REGNUM,    68, 68 }, NULL, NULL },
117     { "badva1", "", 4, 0, eEncodingUint, eFormatAddressInfo, { 69, 69, LLDB_INVALID_REGNUM,    69, 69 }, NULL, NULL },
118     { "ssr"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 70, 70, LLDB_INVALID_REGNUM,    70, 70 }, NULL, NULL },
119     { "ccr"   , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 71, 71, LLDB_INVALID_REGNUM,    71, 71 }, NULL, NULL },
120     { "htid"  , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 72, 72, LLDB_INVALID_REGNUM,    72, 72 }, NULL, NULL },
121 // PADDING {
122     { "p20"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 73, 73, LLDB_INVALID_REGNUM,    73, 73 }, NULL, NULL },
123 // }
124     { "imask" , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 74, 74, LLDB_INVALID_REGNUM,    74, 74 }, NULL, NULL },
125 // PADDING {
126     { "p21"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 75, 75, LLDB_INVALID_REGNUM,    75, 75 }, NULL, NULL },
127     { "p22"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 76, 76, LLDB_INVALID_REGNUM,    76, 76 }, NULL, NULL },
128     { "p23"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 77, 77, LLDB_INVALID_REGNUM,    77, 77 }, NULL, NULL },
129     { "p24"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 78, 78, LLDB_INVALID_REGNUM,    78, 78 }, NULL, NULL },
130     { "p25"   , "", 4, 0, eEncodingInvalid, eFormatInvalid, { 79, 79, LLDB_INVALID_REGNUM,    79, 79 }, NULL, NULL },
131  // }
132     { "g0"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 80, 80, LLDB_INVALID_REGNUM,    80, 80 }, NULL, NULL },
133     { "g1"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 81, 81, LLDB_INVALID_REGNUM,    81, 81 }, NULL, NULL },
134     { "g2"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 82, 82, LLDB_INVALID_REGNUM,    82, 82 }, NULL, NULL },
135     { "g3"    , "", 4, 0, eEncodingUint, eFormatAddressInfo, { 83, 83, LLDB_INVALID_REGNUM,    83, 83 }, NULL, NULL }
136 };
137
138 static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
139 static bool g_register_info_names_constified = false;
140
141 const lldb_private::RegisterInfo *
142 ABISysV_hexagon::GetRegisterInfoArray ( uint32_t &count )
143 {
144     // Make the C-string names and alt_names for the register infos into const 
145     // C-string values by having the ConstString unique the names in the global
146     // constant C-string pool.
147     if (!g_register_info_names_constified)
148     {
149         g_register_info_names_constified = true;
150         for (uint32_t i=0; i<k_num_register_infos; ++i)
151         {
152             if (g_register_infos[i].name)
153                 g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
154             if (g_register_infos[i].alt_name)
155                 g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
156         }
157     }
158     count = k_num_register_infos;
159     return g_register_infos;
160 }
161
162 /*
163     http://en.wikipedia.org/wiki/Red_zone_%28computing%29
164
165     In computing, a red zone is a fixed size area in memory beyond the stack pointer that has not been
166     "allocated". This region of memory is not to be modified by interrupt/exception/signal handlers.
167     This allows the space to be used for temporary data without the extra overhead of modifying the
168     stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC toolchain assumes a
169     128 byte red zone though it is not documented.
170 */
171 size_t
172 ABISysV_hexagon::GetRedZoneSize () const
173 {
174     return 0;
175 }
176
177 //------------------------------------------------------------------
178 // Static Functions
179 //------------------------------------------------------------------
180 ABISP
181 ABISysV_hexagon::CreateInstance ( const ArchSpec &arch )
182 {
183     static ABISP g_abi_sp;
184     if (arch.GetTriple().getArch() == llvm::Triple::hexagon)
185     {
186         if (!g_abi_sp)
187             g_abi_sp.reset (new ABISysV_hexagon);
188         return g_abi_sp;
189     }
190     return ABISP();
191 }
192
193 bool
194 ABISysV_hexagon::PrepareTrivialCall ( Thread &thread, 
195                                       lldb::addr_t  sp    , 
196                                       lldb::addr_t  pc    , 
197                                       lldb::addr_t  ra    , 
198                                       llvm::ArrayRef<addr_t> args ) const
199 {
200     // we don't use the traditional trivial call specialized for jit
201     return false;
202 }
203
204 /*
205
206 // AD:
207 //  . safeguard the current stack
208 //  . how can we know that the called function will create its own frame properly?
209 //  . we could manually make a new stack first:
210 //      2. push RA
211 //      3. push FP
212 //      4. FP = SP
213 //      5. SP = SP ( since no locals in our temp frame )
214
215 // AD 6/05/2014
216 //  . variable argument list parameters are not passed via registers, they are passed on
217 //    the stack.  This presents us with a problem, since we need to know when the valist
218 //    starts.  Currently I can find out if a function is varg, but not how many
219 //    real parameters it takes.  Thus I don't know when to start spilling the vargs.  For
220 //    the time being, to progress, I will assume that it takes on real parameter before
221 //    the vargs list starts.
222
223 // AD 06/05/2014
224 //  . how do we adhere to the stack alignment requirements
225
226 // AD 06/05/2014
227 //  . handle 64bit values and their register / stack requirements
228
229 */
230 #define HEX_ABI_DEBUG 1
231 bool
232 ABISysV_hexagon::PrepareTrivialCall ( Thread &thread, 
233                                       lldb::addr_t  sp  , 
234                                       lldb::addr_t  pc  , 
235                                       lldb::addr_t  ra  , 
236                                       llvm::Type   &prototype,
237                                       llvm::ArrayRef<ABI::CallArgument> args) const
238 {
239     // default number of register passed arguments for varg functions
240     const int nVArgRegParams = 1;
241     Error error;
242
243     // grab the process so we have access to the memory for spilling
244     lldb::ProcessSP proc = thread.GetProcess( );
245
246     // push host data onto target
247     for ( size_t i = 0; i < args.size( ); i++ )
248     {
249         const ABI::CallArgument &arg = args[i];
250         // skip over target values
251         if ( arg.type == ABI::CallArgument::TargetValue )
252             continue;
253         // round up to 8 byte multiple
254         size_t argSize = ( arg.size | 0x7 ) + 1;
255
256         // create space on the stack for this data
257         sp -= argSize;
258
259         // write this argument onto the stack of the host process
260         proc.get( )->WriteMemory( sp, arg.data, arg.size, error );
261         if ( error.Fail( ) )
262             return false;
263
264         // update the argument with the target pointer
265         //XXX: This is a gross hack for getting around the const
266         *((size_t*)(&arg.value)) = sp;
267     }
268
269
270 #if HEX_ABI_DEBUG
271     // print the original stack pointer
272     printf( "sp : %04lx \n", sp );
273 #endif
274
275     // make sure number of parameters matches prototype
276     assert( prototype.getFunctionNumParams( ) == args.size( ) );
277
278     // check if this is a variable argument function
279     bool isVArg = prototype.isFunctionVarArg();
280
281     // get the register context for modifying all of the registers
282     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
283     if (!reg_ctx)
284         return false;
285     
286     // number of arguments passed by register
287     int nRegArgs = nVArgRegParams;
288     if (! isVArg )
289     {
290         // number of arguments is limited by [R0 : R5] space
291         nRegArgs = args.size( );
292         if ( nRegArgs > 6 )
293             nRegArgs = 6;
294     }
295
296     // pass arguments that are passed via registers
297     for ( int i = 0; i < nRegArgs; i++ )
298     {
299         // get the parameter as a u32
300         uint32_t param = (uint32_t)args[i].value;
301         // write argument into register
302         if (!reg_ctx->WriteRegisterFromUnsigned( i, param ))
303             return false;
304     }
305
306     // number of arguments to spill onto stack
307     int nSpillArgs = args.size( ) - nRegArgs;
308     // make space on the stack for arguments
309     sp -= 4 * nSpillArgs;
310     // align stack on an 8 byte boundary
311     if ( sp & 7 )
312         sp -= 4;
313
314     // arguments that are passed on the stack
315     for ( size_t i = nRegArgs, offs=0; i < args.size( ); i++ )
316     {
317         // get the parameter as a u32
318         uint32_t param = (uint32_t)args[i].value;
319         // write argument to stack
320         proc->WriteMemory( sp + offs, (void*)&param, sizeof( param ), error );
321         if ( !error.Success( ) )
322             return false;
323         // 
324         offs += 4;
325     }
326
327     // update registers with current function call state
328     reg_ctx->WriteRegisterFromUnsigned ( 41, pc );
329     reg_ctx->WriteRegisterFromUnsigned ( 31, ra );
330     reg_ctx->WriteRegisterFromUnsigned ( 29, sp );
331 //  reg_ctx->WriteRegisterFromUnsigned ( FP ??? );
332
333 #if HEX_ABI_DEBUG
334     // quick and dirty stack dumper for debugging
335     for ( int i = -8; i < 8; i++ )
336     {
337         uint32_t data = 0;
338         lldb::addr_t addr = sp + i * 4;
339         proc->ReadMemory( addr, (void*)&data, sizeof( data ), error );
340         printf( "\n0x%04lx 0x%08x ", addr, data );
341         if ( i == 0 ) printf( "<<-- sp" );
342     }
343     printf( "\n" );
344 #endif 
345     
346     return true;
347 }
348
349 bool
350 ABISysV_hexagon::GetArgumentValues ( Thread &thread, ValueList &values ) const
351 {
352     return false;
353 }
354
355 Error
356 ABISysV_hexagon::SetReturnValueObject ( lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp )
357 {
358     Error error;
359     return error;
360 }
361
362 ValueObjectSP
363 ABISysV_hexagon::GetReturnValueObjectSimple ( Thread &thread, ClangASTType &return_clang_type ) const
364 {
365     ValueObjectSP return_valobj_sp;
366     return return_valobj_sp;
367 }
368
369 ValueObjectSP
370 ABISysV_hexagon::GetReturnValueObjectImpl ( Thread &thread, ClangASTType &return_clang_type ) const
371 {
372     ValueObjectSP return_valobj_sp;
373     return return_valobj_sp;
374 }
375
376 // called when we are on the first instruction of a new function
377 // for hexagon the return address is in RA (R31)
378 bool
379 ABISysV_hexagon::CreateFunctionEntryUnwindPlan ( UnwindPlan &unwind_plan )
380 {
381     unwind_plan.Clear();
382     unwind_plan.SetRegisterKind(eRegisterKindGeneric);
383     unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
384     
385     UnwindPlan::RowSP row(new UnwindPlan::Row);
386
387     // Our Call Frame Address is the stack pointer value
388     row->SetCFARegister(LLDB_REGNUM_GENERIC_SP);
389     row->SetCFAOffset(4);
390     row->SetOffset(0);
391
392     // The previous PC is in the LR
393     row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_RA, true);
394     unwind_plan.AppendRow(row);
395     
396     unwind_plan.SetSourceName("hexagon at-func-entry default");
397     unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
398     return true;
399 }
400
401 bool
402 ABISysV_hexagon::CreateDefaultUnwindPlan ( UnwindPlan &unwind_plan )
403 {
404     unwind_plan.Clear();
405     unwind_plan.SetRegisterKind(eRegisterKindGeneric);
406
407     uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
408     uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
409     uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
410
411     UnwindPlan::RowSP row(new UnwindPlan::Row);
412
413     row->SetCFARegister(LLDB_REGNUM_GENERIC_FP);
414     row->SetCFAOffset(8);
415
416     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num,-8, true);
417     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num,-4, true);
418     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
419
420     unwind_plan.AppendRow(row);
421     unwind_plan.SetSourceName("hexagon default unwind plan");
422     unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
423     unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
424     return true;
425 }
426
427 /*
428     Register            Usage                                   Saved By
429
430     R0  - R5            parameters(a)                   -
431     R6  - R15           Scratch(b)                              Caller
432     R16 - R27           Scratch                                 Callee
433     R28                         Scratch(b)                              Caller
434     R29 - R31           Stack Frames                    Callee(c)
435     P3:0                        Processor State                 Caller
436
437     a = the caller can change parameter values
438     b = R14 - R15 and R28 are used by the procedure linkage table
439     c = R29 - R31 are saved and restored by allocframe() and deallocframe()
440 */
441 bool
442 ABISysV_hexagon::RegisterIsVolatile ( const RegisterInfo *reg_info )
443 {
444     return !RegisterIsCalleeSaved( reg_info );
445 }
446
447 bool
448 ABISysV_hexagon::RegisterIsCalleeSaved ( const RegisterInfo *reg_info )
449 {
450     int reg = ((reg_info->byte_offset) / 4);
451
452     bool save  = (reg >= 16) && (reg <= 27);
453          save |= (reg >= 29) && (reg <= 32);
454
455     return save;
456 }
457
458 void
459 ABISysV_hexagon::Initialize( void )
460 {
461     PluginManager::RegisterPlugin
462     (
463         GetPluginNameStatic(), 
464         "System V ABI for hexagon targets",
465         CreateInstance
466     );
467 }
468
469 void
470 ABISysV_hexagon::Terminate( void )
471 {
472     PluginManager::UnregisterPlugin( CreateInstance );
473 }
474
475 lldb_private::ConstString
476 ABISysV_hexagon::GetPluginNameStatic()
477 {
478     static ConstString g_name( "sysv-hexagon" );
479     return g_name;
480 }
481
482 //------------------------------------------------------------------
483 // PluginInterface protocol
484 //------------------------------------------------------------------
485 lldb_private::ConstString
486 ABISysV_hexagon::GetPluginName( void )
487 {
488     return GetPluginNameStatic();
489 }
490
491 uint32_t
492 ABISysV_hexagon::GetPluginVersion( void )
493 {
494     return 1;
495 }
496
497 // get value object specialized to work with llvm IR types
498 lldb::ValueObjectSP
499 ABISysV_hexagon::GetReturnValueObjectImpl( lldb_private::Thread &thread, llvm::Type &retType ) const
500 {
501     Value value;
502     ValueObjectSP vObjSP;
503
504     // get the current register context
505     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
506     if (!reg_ctx)
507         return vObjSP;
508
509     // for now just pop R0 to find the return value
510     const lldb_private::RegisterInfo *r0_info = reg_ctx->GetRegisterInfoAtIndex( 0 );
511     if ( r0_info == nullptr )
512         return vObjSP;
513     
514     // void return type
515     if ( retType.isVoidTy( ) )
516     {
517         value.GetScalar( ) = 0;
518     }
519     // integer / pointer return type
520     else
521     if ( retType.isIntegerTy( ) || retType.isPointerTy( ) )
522     {
523         // read r0 register value
524         lldb_private::RegisterValue r0_value;
525         if ( !reg_ctx->ReadRegister( r0_info, r0_value ) )
526             return vObjSP;
527
528         // push r0 into value
529         uint32_t r0_u32 = r0_value.GetAsUInt32( );
530
531         // account for integer size
532         if ( retType.isIntegerTy() && retType.isSized() )
533         {
534             uint64_t size = retType.getScalarSizeInBits( );
535             uint64_t mask = ( 1ull << size ) - 1;
536             // mask out higher order bits then the type we expect
537             r0_u32 &= mask;
538         }
539
540         value.GetScalar( ) = r0_u32;
541     }
542     // unsupported return type
543     else
544         return vObjSP;
545
546     // pack the value into a ValueObjectSP
547     vObjSP = ValueObjectConstResult::Create
548     (
549         thread.GetStackFrameAtIndex(0).get(),
550         value,
551         ConstString("")
552     );
553     return vObjSP;
554 }