[flang][OpenMP] Use range-for to iterate over SymbolSourceMap, NFC
[llvm-project.git] / lldb / source / Plugins / ABI / Hexagon / ABISysV_hexagon.cpp
blob5419f054cbe2df188edbbb20ae3c66ab43ae0cd5
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 //===----------------------------------------------------------------------===//
9 #include "ABISysV_hexagon.h"
11 #include "llvm/IR/DerivedTypes.h"
12 #include "llvm/TargetParser/Triple.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Symbol/UnwindPlan.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/RegisterContext.h"
20 #include "lldb/Target/StackFrame.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Utility/ConstString.h"
24 #include "lldb/Utility/DataExtractor.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/Utility/RegisterValue.h"
27 #include "lldb/Utility/Status.h"
28 #include "lldb/ValueObject/ValueObjectConstResult.h"
29 #include "lldb/ValueObject/ValueObjectMemory.h"
30 #include "lldb/ValueObject/ValueObjectRegister.h"
32 using namespace lldb;
33 using namespace lldb_private;
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)
37 static const RegisterInfo g_register_infos[] = {
38 // hexagon-core.xml
39 {"r00",
40 "",
43 eEncodingUint,
44 eFormatAddressInfo,
45 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
46 nullptr,
47 nullptr,
48 nullptr,
50 {"r01",
51 "",
54 eEncodingUint,
55 eFormatAddressInfo,
56 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
57 nullptr,
58 nullptr,
59 nullptr,
61 {"r02",
62 "",
65 eEncodingUint,
66 eFormatAddressInfo,
67 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
68 nullptr,
69 nullptr,
70 nullptr,
72 {"r03",
73 "",
76 eEncodingUint,
77 eFormatAddressInfo,
78 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
79 nullptr,
80 nullptr,
81 nullptr,
83 {"r04",
84 "",
87 eEncodingUint,
88 eFormatAddressInfo,
89 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
90 nullptr,
91 nullptr,
92 nullptr,
94 {"r05",
95 "",
98 eEncodingUint,
99 eFormatAddressInfo,
100 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
101 nullptr,
102 nullptr,
103 nullptr,
105 {"r06",
109 eEncodingUint,
110 eFormatAddressInfo,
111 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
112 nullptr,
113 nullptr,
114 nullptr,
116 {"r07",
120 eEncodingUint,
121 eFormatAddressInfo,
122 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
123 nullptr,
124 nullptr,
125 nullptr,
127 {"r08",
131 eEncodingUint,
132 eFormatAddressInfo,
133 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
134 nullptr,
135 nullptr,
136 nullptr,
138 {"r09",
142 eEncodingUint,
143 eFormatAddressInfo,
144 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
145 nullptr,
146 nullptr,
147 nullptr,
149 {"r10",
153 eEncodingUint,
154 eFormatAddressInfo,
155 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
156 nullptr,
157 nullptr,
158 nullptr,
160 {"r11",
164 eEncodingUint,
165 eFormatAddressInfo,
166 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
167 nullptr,
168 nullptr,
169 nullptr,
171 {"r12",
175 eEncodingUint,
176 eFormatAddressInfo,
177 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
178 nullptr,
179 nullptr,
180 nullptr,
182 {"r13",
186 eEncodingUint,
187 eFormatAddressInfo,
188 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
189 nullptr,
190 nullptr,
191 nullptr,
193 {"r14",
197 eEncodingUint,
198 eFormatAddressInfo,
199 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
200 nullptr,
201 nullptr,
202 nullptr,
204 {"r15",
208 eEncodingUint,
209 eFormatAddressInfo,
210 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
211 nullptr,
212 nullptr,
213 nullptr,
215 {"r16",
219 eEncodingUint,
220 eFormatAddressInfo,
221 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
222 nullptr,
223 nullptr,
224 nullptr,
226 {"r17",
230 eEncodingUint,
231 eFormatAddressInfo,
232 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
233 nullptr,
234 nullptr,
235 nullptr,
237 {"r18",
241 eEncodingUint,
242 eFormatAddressInfo,
243 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
244 nullptr,
245 nullptr,
246 nullptr,
248 {"r19",
252 eEncodingUint,
253 eFormatAddressInfo,
254 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
255 nullptr,
256 nullptr,
257 nullptr,
259 {"r20",
263 eEncodingUint,
264 eFormatAddressInfo,
265 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
266 nullptr,
267 nullptr,
268 nullptr,
270 {"r21",
274 eEncodingUint,
275 eFormatAddressInfo,
276 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
277 nullptr,
278 nullptr,
279 nullptr,
281 {"r22",
285 eEncodingUint,
286 eFormatAddressInfo,
287 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
288 nullptr,
289 nullptr,
290 nullptr,
292 {"r23",
296 eEncodingUint,
297 eFormatAddressInfo,
298 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
299 nullptr,
300 nullptr,
301 nullptr,
303 {"r24",
307 eEncodingUint,
308 eFormatAddressInfo,
309 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
310 nullptr,
311 nullptr,
312 nullptr,
314 {"r25",
318 eEncodingUint,
319 eFormatAddressInfo,
320 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
321 nullptr,
322 nullptr,
323 nullptr,
325 {"r26",
329 eEncodingUint,
330 eFormatAddressInfo,
331 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
332 nullptr,
333 nullptr,
334 nullptr,
336 {"r27",
340 eEncodingUint,
341 eFormatAddressInfo,
342 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
343 nullptr,
344 nullptr,
345 nullptr,
347 {"r28",
351 eEncodingUint,
352 eFormatAddressInfo,
353 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
354 nullptr,
355 nullptr,
356 nullptr,
358 {"sp",
359 "r29",
362 eEncodingUint,
363 eFormatAddressInfo,
364 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
365 nullptr,
366 nullptr,
367 nullptr,
369 {"fp",
370 "r30",
373 eEncodingUint,
374 eFormatAddressInfo,
375 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
376 nullptr,
377 nullptr,
378 nullptr,
380 {"lr",
381 "r31",
384 eEncodingUint,
385 eFormatAddressInfo,
386 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
387 nullptr,
388 nullptr,
389 nullptr,
391 {"sa0",
395 eEncodingUint,
396 eFormatAddressInfo,
397 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
398 nullptr,
399 nullptr,
400 nullptr,
402 {"lc0",
406 eEncodingUint,
407 eFormatAddressInfo,
408 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
409 nullptr,
410 nullptr,
411 nullptr,
413 {"sa1",
417 eEncodingUint,
418 eFormatAddressInfo,
419 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
420 nullptr,
421 nullptr,
422 nullptr,
424 {"lc1",
428 eEncodingUint,
429 eFormatAddressInfo,
430 {35, 35, LLDB_INVALID_REGNUM, 35, 35},
431 nullptr,
432 nullptr,
433 nullptr,
435 // --> hexagon-v4/5/55/56-sim.xml
436 {"p3_0",
440 eEncodingUint,
441 eFormatAddressInfo,
442 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
443 nullptr,
444 nullptr,
445 nullptr,
448 // PADDING {
449 {"p00",
453 eEncodingInvalid,
454 eFormatInvalid,
455 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
456 nullptr,
457 nullptr,
458 nullptr,
460 // }
461 {"m0",
465 eEncodingUint,
466 eFormatAddressInfo,
467 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
468 nullptr,
469 nullptr,
470 nullptr,
472 {"m1",
476 eEncodingUint,
477 eFormatAddressInfo,
478 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
479 nullptr,
480 nullptr,
481 nullptr,
483 {"usr",
487 eEncodingUint,
488 eFormatAddressInfo,
489 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
490 nullptr,
491 nullptr,
492 nullptr,
494 {"pc",
498 eEncodingUint,
499 eFormatAddressInfo,
500 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
501 nullptr,
502 nullptr,
503 nullptr,
505 {"ugp",
509 eEncodingUint,
510 eFormatAddressInfo,
511 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
512 nullptr,
513 nullptr,
514 nullptr,
516 {"gp",
520 eEncodingUint,
521 eFormatAddressInfo,
522 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
523 nullptr,
524 nullptr,
525 nullptr,
527 {"cs0",
531 eEncodingUint,
532 eFormatAddressInfo,
533 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
534 nullptr,
535 nullptr,
536 nullptr,
538 {"cs1",
542 eEncodingUint,
543 eFormatAddressInfo,
544 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
545 nullptr,
546 nullptr,
547 nullptr,
549 // PADDING {
550 {"p01",
554 eEncodingInvalid,
555 eFormatInvalid,
556 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
557 nullptr,
558 nullptr,
559 nullptr,
561 {"p02",
565 eEncodingInvalid,
566 eFormatInvalid,
567 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
568 nullptr,
569 nullptr,
570 nullptr,
572 {"p03",
576 eEncodingInvalid,
577 eFormatInvalid,
578 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
579 nullptr,
580 nullptr,
581 nullptr,
583 {"p04",
587 eEncodingInvalid,
588 eFormatInvalid,
589 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
590 nullptr,
591 nullptr,
592 nullptr,
594 {"p05",
598 eEncodingInvalid,
599 eFormatInvalid,
600 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
601 nullptr,
602 nullptr,
603 nullptr,
605 {"p06",
609 eEncodingInvalid,
610 eFormatInvalid,
611 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
612 nullptr,
613 nullptr,
614 nullptr,
616 {"p07",
620 eEncodingInvalid,
621 eFormatInvalid,
622 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
623 nullptr,
624 nullptr,
625 nullptr,
627 {"p08",
631 eEncodingInvalid,
632 eFormatInvalid,
633 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
634 nullptr,
635 nullptr,
636 nullptr,
638 {"p09",
642 eEncodingInvalid,
643 eFormatInvalid,
644 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
645 nullptr,
646 nullptr,
647 nullptr,
649 {"p10",
653 eEncodingInvalid,
654 eFormatInvalid,
655 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
656 nullptr,
657 nullptr,
658 nullptr,
660 {"p11",
664 eEncodingInvalid,
665 eFormatInvalid,
666 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
667 nullptr,
668 nullptr,
669 nullptr,
671 {"p12",
675 eEncodingInvalid,
676 eFormatInvalid,
677 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
678 nullptr,
679 nullptr,
680 nullptr,
682 {"p13",
686 eEncodingInvalid,
687 eFormatInvalid,
688 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
689 nullptr,
690 nullptr,
691 nullptr,
693 {"p14",
697 eEncodingInvalid,
698 eFormatInvalid,
699 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
700 nullptr,
701 nullptr,
702 nullptr,
704 {"p15",
708 eEncodingInvalid,
709 eFormatInvalid,
710 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
711 nullptr,
712 nullptr,
713 nullptr,
715 {"p16",
719 eEncodingInvalid,
720 eFormatInvalid,
721 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
722 nullptr,
723 nullptr,
724 nullptr,
726 {"p17",
730 eEncodingInvalid,
731 eFormatInvalid,
732 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
733 nullptr,
734 nullptr,
735 nullptr,
737 {"p18",
741 eEncodingInvalid,
742 eFormatInvalid,
743 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
744 nullptr,
745 nullptr,
746 nullptr,
748 // }
749 {"sgp0",
753 eEncodingUint,
754 eFormatAddressInfo,
755 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
756 nullptr,
757 nullptr,
758 nullptr,
760 // PADDING {
761 {"p19",
765 eEncodingInvalid,
766 eFormatInvalid,
767 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
768 nullptr,
769 nullptr,
770 nullptr,
772 // }
773 {"stid",
777 eEncodingUint,
778 eFormatAddressInfo,
779 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
780 nullptr,
781 nullptr,
782 nullptr,
784 {"elr",
788 eEncodingUint,
789 eFormatAddressInfo,
790 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
791 nullptr,
792 nullptr,
793 nullptr,
795 {"badva0",
799 eEncodingUint,
800 eFormatAddressInfo,
801 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
802 nullptr,
803 nullptr,
804 nullptr,
806 {"badva1",
810 eEncodingUint,
811 eFormatAddressInfo,
812 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
813 nullptr,
814 nullptr,
815 nullptr,
817 {"ssr",
821 eEncodingUint,
822 eFormatAddressInfo,
823 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
824 nullptr,
825 nullptr,
826 nullptr,
828 {"ccr",
832 eEncodingUint,
833 eFormatAddressInfo,
834 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
835 nullptr,
836 nullptr,
837 nullptr,
839 {"htid",
843 eEncodingUint,
844 eFormatAddressInfo,
845 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
846 nullptr,
847 nullptr,
848 nullptr,
850 // PADDING {
851 {"p20",
855 eEncodingInvalid,
856 eFormatInvalid,
857 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
858 nullptr,
859 nullptr,
860 nullptr,
862 // }
863 {"imask",
867 eEncodingUint,
868 eFormatAddressInfo,
869 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
870 nullptr,
871 nullptr,
872 nullptr,
874 // PADDING {
875 {"p21",
879 eEncodingInvalid,
880 eFormatInvalid,
881 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
882 nullptr,
883 nullptr,
884 nullptr,
886 {"p22",
890 eEncodingInvalid,
891 eFormatInvalid,
892 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
893 nullptr,
894 nullptr,
895 nullptr,
897 {"p23",
901 eEncodingInvalid,
902 eFormatInvalid,
903 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
904 nullptr,
905 nullptr,
906 nullptr,
908 {"p24",
912 eEncodingInvalid,
913 eFormatInvalid,
914 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
915 nullptr,
916 nullptr,
917 nullptr,
919 {"p25",
923 eEncodingInvalid,
924 eFormatInvalid,
925 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
926 nullptr,
927 nullptr,
928 nullptr,
930 // }
931 {"g0",
935 eEncodingUint,
936 eFormatAddressInfo,
937 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
938 nullptr,
939 nullptr,
940 nullptr,
942 {"g1",
946 eEncodingUint,
947 eFormatAddressInfo,
948 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
949 nullptr,
950 nullptr,
951 nullptr,
953 {"g2",
957 eEncodingUint,
958 eFormatAddressInfo,
959 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
960 nullptr,
961 nullptr,
962 nullptr,
964 {"g3",
968 eEncodingUint,
969 eFormatAddressInfo,
970 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
971 nullptr,
972 nullptr,
973 nullptr,
976 static const uint32_t k_num_register_infos =
977 sizeof(g_register_infos) / sizeof(RegisterInfo);
979 const lldb_private::RegisterInfo *
980 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
981 count = k_num_register_infos;
982 return g_register_infos;
986 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
988 In computing, a red zone is a fixed size area in memory beyond the stack
989 pointer that has not been
990 "allocated". This region of memory is not to be modified by
991 interrupt/exception/signal handlers.
992 This allows the space to be used for temporary data without the extra
993 overhead of modifying the
994 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
995 toolchain assumes a
996 128 byte red zone though it is not documented.
998 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1000 // Static Functions
1002 ABISP
1003 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1004 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1005 return ABISP(
1006 new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
1008 return ABISP();
1011 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1012 lldb::addr_t pc, lldb::addr_t ra,
1013 llvm::ArrayRef<addr_t> args) const {
1014 // we don't use the traditional trivial call specialized for jit
1015 return false;
1020 // AD:
1021 // . safeguard the current stack
1022 // . how can we know that the called function will create its own frame
1023 properly?
1024 // . we could manually make a new stack first:
1025 // 2. push RA
1026 // 3. push FP
1027 // 4. FP = SP
1028 // 5. SP = SP ( since no locals in our temp frame )
1030 // AD 6/05/2014
1031 // . variable argument list parameters are not passed via registers, they are
1032 passed on
1033 // the stack. This presents us with a problem, since we need to know when
1034 the valist
1035 // starts. Currently I can find out if a function is varg, but not how many
1036 // real parameters it takes. Thus I don't know when to start spilling the
1037 vargs. For
1038 // the time being, to progress, I will assume that it takes on real parameter
1039 before
1040 // the vargs list starts.
1042 // AD 06/05/2014
1043 // . how do we adhere to the stack alignment requirements
1045 // AD 06/05/2014
1046 // . handle 64bit values and their register / stack requirements
1049 #define HEX_ABI_DEBUG 0
1050 bool ABISysV_hexagon::PrepareTrivialCall(
1051 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1052 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1053 // default number of register passed arguments for varg functions
1054 const int nVArgRegParams = 1;
1055 Status error;
1057 // grab the process so we have access to the memory for spilling
1058 lldb::ProcessSP proc = thread.GetProcess();
1060 // get the register context for modifying all of the registers
1061 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1062 if (!reg_ctx)
1063 return false;
1065 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1066 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1067 if (pc_reg == LLDB_INVALID_REGNUM)
1068 return false;
1070 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1071 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1072 if (ra_reg == LLDB_INVALID_REGNUM)
1073 return false;
1075 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1076 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1077 if (sp_reg == LLDB_INVALID_REGNUM)
1078 return false;
1080 // push host data onto target
1081 for (size_t i = 0; i < args.size(); i++) {
1082 const ABI::CallArgument &arg = args[i];
1083 // skip over target values
1084 if (arg.type == ABI::CallArgument::TargetValue)
1085 continue;
1086 // round up to 8 byte multiple
1087 size_t argSize = (arg.size | 0x7) + 1;
1089 // create space on the stack for this data
1090 sp -= argSize;
1092 // write this argument onto the stack of the host process
1093 proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1094 if (error.Fail())
1095 return false;
1097 // update the argument with the target pointer
1098 // XXX: This is a gross hack for getting around the const
1099 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1102 #if HEX_ABI_DEBUG
1103 // print the original stack pointer
1104 printf("sp : %04" PRIx64 " \n", sp);
1105 #endif
1107 // make sure number of parameters matches prototype
1108 assert(prototype.getFunctionNumParams() == args.size());
1110 // check if this is a variable argument function
1111 bool isVArg = prototype.isFunctionVarArg();
1113 // number of arguments passed by register
1114 int nRegArgs = nVArgRegParams;
1115 if (!isVArg) {
1116 // number of arguments is limited by [R0 : R5] space
1117 nRegArgs = args.size();
1118 if (nRegArgs > 6)
1119 nRegArgs = 6;
1122 // pass arguments that are passed via registers
1123 for (int i = 0; i < nRegArgs; i++) {
1124 // get the parameter as a u32
1125 uint32_t param = (uint32_t)args[i].value;
1126 // write argument into register
1127 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1128 return false;
1131 // number of arguments to spill onto stack
1132 int nSpillArgs = args.size() - nRegArgs;
1133 // make space on the stack for arguments
1134 sp -= 4 * nSpillArgs;
1135 // align stack on an 8 byte boundary
1136 if (sp & 7)
1137 sp -= 4;
1139 // arguments that are passed on the stack
1140 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1141 // get the parameter as a u32
1142 uint32_t param = (uint32_t)args[i].value;
1143 // write argument to stack
1144 proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
1145 if (!error.Success())
1146 return false;
1148 offs += 4;
1151 // update registers with current function call state
1152 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1153 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1154 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1156 #if HEX_ABI_DEBUG
1157 // quick and dirty stack dumper for debugging
1158 for (int i = -8; i < 8; i++) {
1159 uint32_t data = 0;
1160 lldb::addr_t addr = sp + i * 4;
1161 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1162 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1163 if (i == 0)
1164 printf("<<-- sp");
1166 printf("\n");
1167 #endif
1169 return true;
1172 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1173 ValueList &values) const {
1174 return false;
1177 Status
1178 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1179 lldb::ValueObjectSP &new_value_sp) {
1180 Status error;
1181 return error;
1184 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1185 Thread &thread, CompilerType &return_compiler_type) const {
1186 ValueObjectSP return_valobj_sp;
1187 return return_valobj_sp;
1190 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1191 Thread &thread, CompilerType &return_compiler_type) const {
1192 ValueObjectSP return_valobj_sp;
1193 return return_valobj_sp;
1196 // called when we are on the first instruction of a new function for hexagon
1197 // the return address is in RA (R31)
1198 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1199 unwind_plan.Clear();
1200 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1201 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1203 UnwindPlan::RowSP row(new UnwindPlan::Row);
1205 // Our Call Frame Address is the stack pointer value
1206 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1207 row->SetOffset(0);
1209 // The previous PC is in the LR
1210 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1211 LLDB_REGNUM_GENERIC_RA, true);
1212 unwind_plan.AppendRow(row);
1214 unwind_plan.SetSourceName("hexagon at-func-entry default");
1215 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1216 return true;
1219 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1220 unwind_plan.Clear();
1221 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1223 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1224 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1225 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1227 UnwindPlan::RowSP row(new UnwindPlan::Row);
1229 row->SetUnspecifiedRegistersAreUndefined(true);
1230 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1232 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1233 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1234 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1236 unwind_plan.AppendRow(row);
1237 unwind_plan.SetSourceName("hexagon default unwind plan");
1238 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1239 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1240 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1241 return true;
1245 Register Usage Saved By
1247 R0 - R5 parameters(a) -
1248 R6 - R15 Scratch(b) Caller
1249 R16 - R27 Scratch Callee
1250 R28 Scratch(b) Caller
1251 R29 - R31 Stack Frames Callee(c)
1252 P3:0 Processor State Caller
1254 a = the caller can change parameter values
1255 b = R14 - R15 and R28 are used by the procedure linkage table
1256 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1258 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1259 return !RegisterIsCalleeSaved(reg_info);
1262 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1263 int reg = ((reg_info->byte_offset) / 4);
1265 bool save = (reg >= 16) && (reg <= 27);
1266 save |= (reg >= 29) && (reg <= 32);
1268 return save;
1271 void ABISysV_hexagon::Initialize() {
1272 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1273 "System V ABI for hexagon targets",
1274 CreateInstance);
1277 void ABISysV_hexagon::Terminate() {
1278 PluginManager::UnregisterPlugin(CreateInstance);
1281 // get value object specialized to work with llvm IR types
1282 lldb::ValueObjectSP
1283 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1284 llvm::Type &retType) const {
1285 Value value;
1286 ValueObjectSP vObjSP;
1288 // get the current register context
1289 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1290 if (!reg_ctx)
1291 return vObjSP;
1293 // for now just pop R0 to find the return value
1294 const lldb_private::RegisterInfo *r0_info =
1295 reg_ctx->GetRegisterInfoAtIndex(0);
1296 if (r0_info == nullptr)
1297 return vObjSP;
1299 // void return type
1300 if (retType.isVoidTy()) {
1301 value.GetScalar() = 0;
1303 // integer / pointer return type
1304 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1305 // read r0 register value
1306 lldb_private::RegisterValue r0_value;
1307 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1308 return vObjSP;
1310 // push r0 into value
1311 uint32_t r0_u32 = r0_value.GetAsUInt32();
1313 // account for integer size
1314 if (retType.isIntegerTy() && retType.isSized()) {
1315 uint64_t size = retType.getScalarSizeInBits();
1316 uint64_t mask = (1ull << size) - 1;
1317 // mask out higher order bits then the type we expect
1318 r0_u32 &= mask;
1321 value.GetScalar() = r0_u32;
1323 // unsupported return type
1324 else
1325 return vObjSP;
1327 // pack the value into a ValueObjectSP
1328 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1329 value, ConstString(""));
1330 return vObjSP;