LLDB mainline
ABISysV_hexagon.cpp
Go to the documentation of this file.
1//===-- ABISysV_hexagon.cpp -----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ABISysV_hexagon.h"
10
11#include "llvm/IR/DerivedTypes.h"
12#include "llvm/TargetParser/Triple.h"
13
14#include "lldb/Core/Module.h"
16#include "lldb/Core/Value.h"
21#include "lldb/Target/Process.h"
24#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
28#include "lldb/Utility/Log.h"
30#include "lldb/Utility/Status.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
36
37static const RegisterInfo g_register_infos[] = {
38 // hexagon-core.xml
39 {"r00",
40 "",
41 4,
42 0,
45 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
46 nullptr,
47 nullptr,
48 },
49 {"r01",
50 "",
51 4,
52 0,
55 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
56 nullptr,
57 nullptr,
58 },
59 {"r02",
60 "",
61 4,
62 0,
65 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
66 nullptr,
67 nullptr,
68 },
69 {"r03",
70 "",
71 4,
72 0,
75 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
76 nullptr,
77 nullptr,
78 },
79 {"r04",
80 "",
81 4,
82 0,
85 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
86 nullptr,
87 nullptr,
88 },
89 {"r05",
90 "",
91 4,
92 0,
95 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
96 nullptr,
97 nullptr,
98 },
99 {"r06",
100 "",
101 4,
102 0,
105 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
106 nullptr,
107 nullptr,
108 },
109 {"r07",
110 "",
111 4,
112 0,
115 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
116 nullptr,
117 nullptr,
118 },
119 {"r08",
120 "",
121 4,
122 0,
125 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
126 nullptr,
127 nullptr,
128 },
129 {"r09",
130 "",
131 4,
132 0,
135 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
136 nullptr,
137 nullptr,
138 },
139 {"r10",
140 "",
141 4,
142 0,
145 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
146 nullptr,
147 nullptr,
148 },
149 {"r11",
150 "",
151 4,
152 0,
155 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
156 nullptr,
157 nullptr,
158 },
159 {"r12",
160 "",
161 4,
162 0,
165 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
166 nullptr,
167 nullptr,
168 },
169 {"r13",
170 "",
171 4,
172 0,
175 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
176 nullptr,
177 nullptr,
178 },
179 {"r14",
180 "",
181 4,
182 0,
185 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
186 nullptr,
187 nullptr,
188 },
189 {"r15",
190 "",
191 4,
192 0,
195 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
196 nullptr,
197 nullptr,
198 },
199 {"r16",
200 "",
201 4,
202 0,
205 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
206 nullptr,
207 nullptr,
208 },
209 {"r17",
210 "",
211 4,
212 0,
215 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
216 nullptr,
217 nullptr,
218 },
219 {"r18",
220 "",
221 4,
222 0,
225 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
226 nullptr,
227 nullptr,
228 },
229 {"r19",
230 "",
231 4,
232 0,
235 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
236 nullptr,
237 nullptr,
238 },
239 {"r20",
240 "",
241 4,
242 0,
245 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
246 nullptr,
247 nullptr,
248 },
249 {"r21",
250 "",
251 4,
252 0,
255 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
256 nullptr,
257 nullptr,
258 },
259 {"r22",
260 "",
261 4,
262 0,
265 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
266 nullptr,
267 nullptr,
268 },
269 {"r23",
270 "",
271 4,
272 0,
275 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
276 nullptr,
277 nullptr,
278 },
279 {"r24",
280 "",
281 4,
282 0,
285 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
286 nullptr,
287 nullptr,
288 },
289 {"r25",
290 "",
291 4,
292 0,
295 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
296 nullptr,
297 nullptr,
298 },
299 {"r26",
300 "",
301 4,
302 0,
305 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
306 nullptr,
307 nullptr,
308 },
309 {"r27",
310 "",
311 4,
312 0,
315 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
316 nullptr,
317 nullptr,
318 },
319 {"r28",
320 "",
321 4,
322 0,
325 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
326 nullptr,
327 nullptr,
328 },
329 {"sp",
330 "r29",
331 4,
332 0,
335 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
336 nullptr,
337 nullptr,
338 },
339 {"fp",
340 "r30",
341 4,
342 0,
345 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
346 nullptr,
347 nullptr,
348 },
349 {"lr",
350 "r31",
351 4,
352 0,
355 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
356 nullptr,
357 nullptr,
358 },
359 {"sa0",
360 "",
361 4,
362 0,
365 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
366 nullptr,
367 nullptr,
368 },
369 {"lc0",
370 "",
371 4,
372 0,
375 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
376 nullptr,
377 nullptr,
378 },
379 {"sa1",
380 "",
381 4,
382 0,
385 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
386 nullptr,
387 nullptr,
388 },
389 {"lc1",
390 "",
391 4,
392 0,
395 {35, 35, LLDB_INVALID_REGNUM, 35, 35},
396 nullptr,
397 nullptr,
398 },
399 // --> hexagon-v4/5/55/56-sim.xml
400 {"p3_0",
401 "",
402 4,
403 0,
406 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
407 nullptr,
408 nullptr,
409 },
410 // PADDING {
411 {"p00",
412 "",
413 4,
414 0,
417 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
418 nullptr,
419 nullptr,
420 },
421 // }
422 {"m0",
423 "",
424 4,
425 0,
428 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
429 nullptr,
430 nullptr,
431 },
432 {"m1",
433 "",
434 4,
435 0,
438 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
439 nullptr,
440 nullptr,
441 },
442 {"usr",
443 "",
444 4,
445 0,
448 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
449 nullptr,
450 nullptr,
451 },
452 {"pc",
453 "",
454 4,
455 0,
458 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
459 nullptr,
460 nullptr,
461 },
462 {"ugp",
463 "",
464 4,
465 0,
468 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
469 nullptr,
470 nullptr,
471 },
472 {"gp",
473 "",
474 4,
475 0,
478 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
479 nullptr,
480 nullptr,
481 },
482 {"cs0",
483 "",
484 4,
485 0,
488 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
489 nullptr,
490 nullptr,
491 },
492 {"cs1",
493 "",
494 4,
495 0,
498 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
499 nullptr,
500 nullptr,
501 },
502 // PADDING {
503 {"p01",
504 "",
505 4,
506 0,
509 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
510 nullptr,
511 nullptr,
512 },
513 {"p02",
514 "",
515 4,
516 0,
519 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
520 nullptr,
521 nullptr,
522 },
523 {"p03",
524 "",
525 4,
526 0,
529 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
530 nullptr,
531 nullptr,
532 },
533 {"p04",
534 "",
535 4,
536 0,
539 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
540 nullptr,
541 nullptr,
542 },
543 {"p05",
544 "",
545 4,
546 0,
549 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
550 nullptr,
551 nullptr,
552 },
553 {"p06",
554 "",
555 4,
556 0,
559 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
560 nullptr,
561 nullptr,
562 },
563 {"p07",
564 "",
565 4,
566 0,
569 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
570 nullptr,
571 nullptr,
572 },
573 {"p08",
574 "",
575 4,
576 0,
579 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
580 nullptr,
581 nullptr,
582 },
583 {"p09",
584 "",
585 4,
586 0,
589 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
590 nullptr,
591 nullptr,
592 },
593 {"p10",
594 "",
595 4,
596 0,
599 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
600 nullptr,
601 nullptr,
602 },
603 {"p11",
604 "",
605 4,
606 0,
609 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
610 nullptr,
611 nullptr,
612 },
613 {"p12",
614 "",
615 4,
616 0,
619 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
620 nullptr,
621 nullptr,
622 },
623 {"p13",
624 "",
625 4,
626 0,
629 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
630 nullptr,
631 nullptr,
632 },
633 {"p14",
634 "",
635 4,
636 0,
639 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
640 nullptr,
641 nullptr,
642 },
643 {"p15",
644 "",
645 4,
646 0,
649 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
650 nullptr,
651 nullptr,
652 },
653 {"p16",
654 "",
655 4,
656 0,
659 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
660 nullptr,
661 nullptr,
662 },
663 {"p17",
664 "",
665 4,
666 0,
669 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
670 nullptr,
671 nullptr,
672 },
673 {"p18",
674 "",
675 4,
676 0,
679 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
680 nullptr,
681 nullptr,
682 },
683 // }
684 {"sgp0",
685 "",
686 4,
687 0,
690 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
691 nullptr,
692 nullptr,
693 },
694 // PADDING {
695 {"p19",
696 "",
697 4,
698 0,
701 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
702 nullptr,
703 nullptr,
704 },
705 // }
706 {"stid",
707 "",
708 4,
709 0,
712 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
713 nullptr,
714 nullptr,
715 },
716 {"elr",
717 "",
718 4,
719 0,
722 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
723 nullptr,
724 nullptr,
725 },
726 {"badva0",
727 "",
728 4,
729 0,
732 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
733 nullptr,
734 nullptr,
735 },
736 {"badva1",
737 "",
738 4,
739 0,
742 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
743 nullptr,
744 nullptr,
745 },
746 {"ssr",
747 "",
748 4,
749 0,
752 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
753 nullptr,
754 nullptr,
755 },
756 {"ccr",
757 "",
758 4,
759 0,
762 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
763 nullptr,
764 nullptr,
765 },
766 {"htid",
767 "",
768 4,
769 0,
772 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
773 nullptr,
774 nullptr,
775 },
776 // PADDING {
777 {"p20",
778 "",
779 4,
780 0,
783 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
784 nullptr,
785 nullptr,
786 },
787 // }
788 {"imask",
789 "",
790 4,
791 0,
794 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
795 nullptr,
796 nullptr,
797 },
798 // PADDING {
799 {"p21",
800 "",
801 4,
802 0,
805 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
806 nullptr,
807 nullptr,
808 },
809 {"p22",
810 "",
811 4,
812 0,
815 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
816 nullptr,
817 nullptr,
818 },
819 {"p23",
820 "",
821 4,
822 0,
825 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
826 nullptr,
827 nullptr,
828 },
829 {"p24",
830 "",
831 4,
832 0,
835 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
836 nullptr,
837 nullptr,
838 },
839 {"p25",
840 "",
841 4,
842 0,
845 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
846 nullptr,
847 nullptr,
848 },
849 // }
850 {"g0",
851 "",
852 4,
853 0,
856 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
857 nullptr,
858 nullptr,
859 },
860 {"g1",
861 "",
862 4,
863 0,
866 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
867 nullptr,
868 nullptr,
869 },
870 {"g2",
871 "",
872 4,
873 0,
876 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
877 nullptr,
878 nullptr,
879 },
880 {"g3",
881 "",
882 4,
883 0,
886 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
887 nullptr,
888 nullptr,
889 }};
890
892 sizeof(g_register_infos) / sizeof(RegisterInfo);
893
894const lldb_private::RegisterInfo *
896 count = k_num_register_infos;
897 return g_register_infos;
898}
899
900/*
901 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
902
903 In computing, a red zone is a fixed size area in memory beyond the stack
904 pointer that has not been
905 "allocated". This region of memory is not to be modified by
906 interrupt/exception/signal handlers.
907 This allows the space to be used for temporary data without the extra
908 overhead of modifying the
909 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
910 toolchain assumes a
911 128 byte red zone though it is not documented.
912*/
913size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
914
915// Static Functions
916
917ABISP
918ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
919 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
920 return ABISP(
921 new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
922 }
923 return ABISP();
924}
925
928 llvm::ArrayRef<addr_t> args) const {
929 // we don't use the traditional trivial call specialized for jit
930 return false;
931}
932
933/*
934
935// AD:
936// . safeguard the current stack
937// . how can we know that the called function will create its own frame
938properly?
939// . we could manually make a new stack first:
940// 2. push RA
941// 3. push FP
942// 4. FP = SP
943// 5. SP = SP ( since no locals in our temp frame )
944
945// AD 6/05/2014
946// . variable argument list parameters are not passed via registers, they are
947passed on
948// the stack. This presents us with a problem, since we need to know when
949the valist
950// starts. Currently I can find out if a function is varg, but not how many
951// real parameters it takes. Thus I don't know when to start spilling the
952vargs. For
953// the time being, to progress, I will assume that it takes on real parameter
954before
955// the vargs list starts.
956
957// AD 06/05/2014
958// . how do we adhere to the stack alignment requirements
959
960// AD 06/05/2014
961// . handle 64bit values and their register / stack requirements
962
963*/
964#define HEX_ABI_DEBUG 0
967 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
968 // default number of register passed arguments for varg functions
969 const int nVArgRegParams = 1;
971
972 // grab the process so we have access to the memory for spilling
973 lldb::ProcessSP proc = thread.GetProcess();
974
975 // get the register context for modifying all of the registers
976 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
977 if (!reg_ctx)
978 return false;
979
982 if (pc_reg == LLDB_INVALID_REGNUM)
983 return false;
984
987 if (ra_reg == LLDB_INVALID_REGNUM)
988 return false;
989
992 if (sp_reg == LLDB_INVALID_REGNUM)
993 return false;
994
995 // push host data onto target
996 for (size_t i = 0; i < args.size(); i++) {
997 const ABI::CallArgument &arg = args[i];
998 // skip over target values
1000 continue;
1001 // round up to 8 byte multiple
1002 size_t argSize = (arg.size | 0x7) + 1;
1003
1004 // create space on the stack for this data
1005 sp -= argSize;
1006
1007 // write this argument onto the stack of the host process
1008 proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1009 if (error.Fail())
1010 return false;
1011
1012 // update the argument with the target pointer
1013 // XXX: This is a gross hack for getting around the const
1014 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1015 }
1016
1017#if HEX_ABI_DEBUG
1018 // print the original stack pointer
1019 printf("sp : %04" PRIx64 " \n", sp);
1020#endif
1021
1022 // make sure number of parameters matches prototype
1023 assert(prototype.getFunctionNumParams() == args.size());
1024
1025 // check if this is a variable argument function
1026 bool isVArg = prototype.isFunctionVarArg();
1027
1028 // number of arguments passed by register
1029 int nRegArgs = nVArgRegParams;
1030 if (!isVArg) {
1031 // number of arguments is limited by [R0 : R5] space
1032 nRegArgs = args.size();
1033 if (nRegArgs > 6)
1034 nRegArgs = 6;
1035 }
1036
1037 // pass arguments that are passed via registers
1038 for (int i = 0; i < nRegArgs; i++) {
1039 // get the parameter as a u32
1040 uint32_t param = (uint32_t)args[i].value;
1041 // write argument into register
1042 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1043 return false;
1044 }
1045
1046 // number of arguments to spill onto stack
1047 int nSpillArgs = args.size() - nRegArgs;
1048 // make space on the stack for arguments
1049 sp -= 4 * nSpillArgs;
1050 // align stack on an 8 byte boundary
1051 if (sp & 7)
1052 sp -= 4;
1053
1054 // arguments that are passed on the stack
1055 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1056 // get the parameter as a u32
1057 uint32_t param = (uint32_t)args[i].value;
1058 // write argument to stack
1059 proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
1060 if (!error.Success())
1061 return false;
1062 //
1063 offs += 4;
1064 }
1065
1066 // update registers with current function call state
1067 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1068 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1069 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1070
1071#if HEX_ABI_DEBUG
1072 // quick and dirty stack dumper for debugging
1073 for (int i = -8; i < 8; i++) {
1074 uint32_t data = 0;
1075 lldb::addr_t addr = sp + i * 4;
1076 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1077 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1078 if (i == 0)
1079 printf("<<-- sp");
1080 }
1081 printf("\n");
1082#endif
1083
1084 return true;
1085}
1086
1088 ValueList &values) const {
1089 return false;
1090}
1091
1092Status
1093ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1094 lldb::ValueObjectSP &new_value_sp) {
1095 Status error;
1096 return error;
1097}
1098
1100 Thread &thread, CompilerType &return_compiler_type) const {
1101 ValueObjectSP return_valobj_sp;
1102 return return_valobj_sp;
1103}
1104
1106 Thread &thread, CompilerType &return_compiler_type) const {
1107 ValueObjectSP return_valobj_sp;
1108 return return_valobj_sp;
1109}
1110
1111// called when we are on the first instruction of a new function for hexagon
1112// the return address is in RA (R31)
1114 unwind_plan.Clear();
1117
1119
1120 // Our Call Frame Address is the stack pointer value
1121 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1122 row->SetOffset(0);
1123
1124 // The previous PC is in the LR
1125 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1127 unwind_plan.AppendRow(row);
1128
1129 unwind_plan.SetSourceName("hexagon at-func-entry default");
1131 return true;
1132}
1133
1135 unwind_plan.Clear();
1137
1138 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1139 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1140 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1141
1143
1144 row->SetUnspecifiedRegistersAreUndefined(true);
1145 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1146
1147 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1148 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1149 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1150
1151 unwind_plan.AppendRow(row);
1152 unwind_plan.SetSourceName("hexagon default unwind plan");
1156 return true;
1157}
1158
1159/*
1160 Register Usage Saved By
1161
1162 R0 - R5 parameters(a) -
1163 R6 - R15 Scratch(b) Caller
1164 R16 - R27 Scratch Callee
1165 R28 Scratch(b) Caller
1166 R29 - R31 Stack Frames Callee(c)
1167 P3:0 Processor State Caller
1168
1169 a = the caller can change parameter values
1170 b = R14 - R15 and R28 are used by the procedure linkage table
1171 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1172*/
1173bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1174 return !RegisterIsCalleeSaved(reg_info);
1175}
1176
1177bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1178 int reg = ((reg_info->byte_offset) / 4);
1179
1180 bool save = (reg >= 16) && (reg <= 27);
1181 save |= (reg >= 29) && (reg <= 32);
1182
1183 return save;
1184}
1185
1188 "System V ABI for hexagon targets",
1190}
1191
1194}
1195
1196// get value object specialized to work with llvm IR types
1197lldb::ValueObjectSP
1199 llvm::Type &retType) const {
1200 Value value;
1201 ValueObjectSP vObjSP;
1202
1203 // get the current register context
1204 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1205 if (!reg_ctx)
1206 return vObjSP;
1207
1208 // for now just pop R0 to find the return value
1209 const lldb_private::RegisterInfo *r0_info =
1210 reg_ctx->GetRegisterInfoAtIndex(0);
1211 if (r0_info == nullptr)
1212 return vObjSP;
1213
1214 // void return type
1215 if (retType.isVoidTy()) {
1216 value.GetScalar() = 0;
1217 }
1218 // integer / pointer return type
1219 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1220 // read r0 register value
1222 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1223 return vObjSP;
1224
1225 // push r0 into value
1226 uint32_t r0_u32 = r0_value.GetAsUInt32();
1227
1228 // account for integer size
1229 if (retType.isIntegerTy() && retType.isSized()) {
1230 uint64_t size = retType.getScalarSizeInBits();
1231 uint64_t mask = (1ull << size) - 1;
1232 // mask out higher order bits then the type we expect
1233 r0_u32 &= mask;
1234 }
1235
1236 value.GetScalar() = r0_u32;
1237 }
1238 // unsupported return type
1239 else
1240 return vObjSP;
1241
1242 // pack the value into a ValueObjectSP
1244 value, ConstString(""));
1245 return vObjSP;
1246}
static const uint32_t k_num_register_infos
static const RegisterInfo g_register_infos[]
static const uint32_t k_num_register_infos
static const RegisterInfo g_register_infos[]
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
Definition: PluginManager.h:25
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
static llvm::StringRef GetPluginNameStatic()
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
static void Initialize()
static void Terminate()
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
size_t GetRedZoneSize() const override
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
Definition: ABI.cpp:201
An architecture specification class.
Definition: ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:39
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
An error handling class.
Definition: Status.h:44
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:502
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:437
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:439
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:478
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:490
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
const Scalar & GetScalar() const
Definition: Value.h:112
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:54
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:52
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:51
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:53
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
@ eFormatAddressInfo
Describe what an address points to (func + offset.
@ eEncodingUint
unsigned integer
@ eEncodingInvalid
uint64_t addr_t
Definition: lldb-types.h:83
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
std::unique_ptr< uint8_t[]> data_up
Definition: ABI.h:38