10SN/A//===-- ABISysV_arm.cpp ---------------------------------------------------===//
26537SN/A//
30SN/A// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40SN/A// See https://llvm.org/LICENSE.txt for license information.
50SN/A// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60SN/A//
72362SN/A//===----------------------------------------------------------------------===//
80SN/A
92362SN/A#include "ABISysV_arm.h"
100SN/A
110SN/A#include <optional>
120SN/A#include <vector>
130SN/A
140SN/A#include "llvm/ADT/STLExtras.h"
150SN/A#include "llvm/TargetParser/Triple.h"
160SN/A
170SN/A#include "lldb/Core/Module.h"
180SN/A#include "lldb/Core/PluginManager.h"
190SN/A#include "lldb/Core/Value.h"
200SN/A#include "lldb/Core/ValueObjectConstResult.h"
212362SN/A#include "lldb/Symbol/UnwindPlan.h"
222362SN/A#include "lldb/Target/Process.h"
232362SN/A#include "lldb/Target/RegisterContext.h"
240SN/A#include "lldb/Target/Target.h"
250SN/A#include "lldb/Target/Thread.h"
260SN/A#include "lldb/Utility/ConstString.h"
270SN/A#include "lldb/Utility/RegisterValue.h"
280SN/A#include "lldb/Utility/Scalar.h"
290SN/A#include "lldb/Utility/Status.h"
300SN/A
310SN/A#include "Plugins/Process/Utility/ARMDefines.h"
320SN/A#include "Utility/ARM_DWARF_Registers.h"
330SN/A#include "Utility/ARM_ehframe_Registers.h"
340SN/A
350SN/Ausing namespace lldb;
360SN/Ausing namespace lldb_private;
370SN/A
380SN/ALLDB_PLUGIN_DEFINE(ABISysV_arm)
390SN/A
4010071SN/Astatic const RegisterInfo g_register_infos[] = {
410SN/A    //  NAME       ALT       SZ OFF ENCODING         FORMAT          EH_FRAME
426537SN/A    //  DWARF               GENERIC                     PROCESS PLUGIN
436537SN/A    //  LLDB NATIVE            VALUE REGS    INVALIDATE REGS
440SN/A    //  ========== =======   == === =============    ============
450SN/A    //  ======================= =================== ===========================
460SN/A    //  ======================= ====================== ==========
470SN/A    //  ===============
480SN/A    {"r0",
490SN/A     nullptr,
500SN/A     4,
510SN/A     0,
520SN/A     eEncodingUint,
530SN/A     eFormatHex,
54     {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
55      LLDB_INVALID_REGNUM},
56     nullptr,
57     nullptr,
58     nullptr,
59    },
60    {"r1",
61     nullptr,
62     4,
63     0,
64     eEncodingUint,
65     eFormatHex,
66     {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
67      LLDB_INVALID_REGNUM},
68     nullptr,
69     nullptr,
70     nullptr,
71    },
72    {"r2",
73     nullptr,
74     4,
75     0,
76     eEncodingUint,
77     eFormatHex,
78     {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
79      LLDB_INVALID_REGNUM},
80     nullptr,
81     nullptr,
82     nullptr,
83    },
84    {"r3",
85     nullptr,
86     4,
87     0,
88     eEncodingUint,
89     eFormatHex,
90     {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
91      LLDB_INVALID_REGNUM},
92     nullptr,
93     nullptr,
94     nullptr,
95    },
96    {"r4",
97     nullptr,
98     4,
99     0,
100     eEncodingUint,
101     eFormatHex,
102     {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
103      LLDB_INVALID_REGNUM},
104     nullptr,
105     nullptr,
106     nullptr,
107    },
108    {"r5",
109     nullptr,
110     4,
111     0,
112     eEncodingUint,
113     eFormatHex,
114     {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
115      LLDB_INVALID_REGNUM},
116     nullptr,
117     nullptr,
118     nullptr,
119    },
120    {"r6",
121     nullptr,
122     4,
123     0,
124     eEncodingUint,
125     eFormatHex,
126     {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
127      LLDB_INVALID_REGNUM},
128     nullptr,
129     nullptr,
130     nullptr,
131    },
132    {"r7",
133     nullptr,
134     4,
135     0,
136     eEncodingUint,
137     eFormatHex,
138     {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
139      LLDB_INVALID_REGNUM},
140     nullptr,
141     nullptr,
142     nullptr,
143    },
144    {"r8",
145     nullptr,
146     4,
147     0,
148     eEncodingUint,
149     eFormatHex,
150     {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
151      LLDB_INVALID_REGNUM},
152     nullptr,
153     nullptr,
154     nullptr,
155    },
156    {"r9",
157     nullptr,
158     4,
159     0,
160     eEncodingUint,
161     eFormatHex,
162     {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
163      LLDB_INVALID_REGNUM},
164     nullptr,
165     nullptr,
166     nullptr,
167    },
168    {"r10",
169     nullptr,
170     4,
171     0,
172     eEncodingUint,
173     eFormatHex,
174     {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
175      LLDB_INVALID_REGNUM},
176     nullptr,
177     nullptr,
178     nullptr,
179    },
180    {"r11",
181     nullptr,
182     4,
183     0,
184     eEncodingUint,
185     eFormatHex,
186     {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
187      LLDB_INVALID_REGNUM},
188     nullptr,
189     nullptr,
190     nullptr,
191    },
192    {"r12",
193     nullptr,
194     4,
195     0,
196     eEncodingUint,
197     eFormatHex,
198     {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199      LLDB_INVALID_REGNUM},
200     nullptr,
201     nullptr,
202     nullptr,
203    },
204    {"sp",
205     "r13",
206     4,
207     0,
208     eEncodingUint,
209     eFormatHex,
210     {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
211      LLDB_INVALID_REGNUM},
212     nullptr,
213     nullptr,
214     nullptr,
215    },
216    {"lr",
217     "r14",
218     4,
219     0,
220     eEncodingUint,
221     eFormatHex,
222     {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
223      LLDB_INVALID_REGNUM},
224     nullptr,
225     nullptr,
226     nullptr,
227    },
228    {"pc",
229     "r15",
230     4,
231     0,
232     eEncodingUint,
233     eFormatHex,
234     {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
235      LLDB_INVALID_REGNUM},
236     nullptr,
237     nullptr,
238     nullptr,
239    },
240    {"cpsr",
241     "psr",
242     4,
243     0,
244     eEncodingUint,
245     eFormatHex,
246     {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
247      LLDB_INVALID_REGNUM},
248     nullptr,
249     nullptr,
250     nullptr,
251    },
252    {"s0",
253     nullptr,
254     4,
255     0,
256     eEncodingIEEE754,
257     eFormatFloat,
258     {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259      LLDB_INVALID_REGNUM},
260     nullptr,
261     nullptr,
262     nullptr,
263    },
264    {"s1",
265     nullptr,
266     4,
267     0,
268     eEncodingIEEE754,
269     eFormatFloat,
270     {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271      LLDB_INVALID_REGNUM},
272     nullptr,
273     nullptr,
274     nullptr,
275    },
276    {"s2",
277     nullptr,
278     4,
279     0,
280     eEncodingIEEE754,
281     eFormatFloat,
282     {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283      LLDB_INVALID_REGNUM},
284     nullptr,
285     nullptr,
286     nullptr,
287    },
288    {"s3",
289     nullptr,
290     4,
291     0,
292     eEncodingIEEE754,
293     eFormatFloat,
294     {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
295      LLDB_INVALID_REGNUM},
296     nullptr,
297     nullptr,
298     nullptr,
299    },
300    {"s4",
301     nullptr,
302     4,
303     0,
304     eEncodingIEEE754,
305     eFormatFloat,
306     {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307      LLDB_INVALID_REGNUM},
308     nullptr,
309     nullptr,
310     nullptr,
311    },
312    {"s5",
313     nullptr,
314     4,
315     0,
316     eEncodingIEEE754,
317     eFormatFloat,
318     {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
319      LLDB_INVALID_REGNUM},
320     nullptr,
321     nullptr,
322     nullptr,
323    },
324    {"s6",
325     nullptr,
326     4,
327     0,
328     eEncodingIEEE754,
329     eFormatFloat,
330     {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
331      LLDB_INVALID_REGNUM},
332     nullptr,
333     nullptr,
334     nullptr,
335    },
336    {"s7",
337     nullptr,
338     4,
339     0,
340     eEncodingIEEE754,
341     eFormatFloat,
342     {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
343      LLDB_INVALID_REGNUM},
344     nullptr,
345     nullptr,
346     nullptr,
347    },
348    {"s8",
349     nullptr,
350     4,
351     0,
352     eEncodingIEEE754,
353     eFormatFloat,
354     {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355      LLDB_INVALID_REGNUM},
356     nullptr,
357     nullptr,
358     nullptr,
359    },
360    {"s9",
361     nullptr,
362     4,
363     0,
364     eEncodingIEEE754,
365     eFormatFloat,
366     {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
367      LLDB_INVALID_REGNUM},
368     nullptr,
369     nullptr,
370     nullptr,
371    },
372    {"s10",
373     nullptr,
374     4,
375     0,
376     eEncodingIEEE754,
377     eFormatFloat,
378     {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
379      LLDB_INVALID_REGNUM},
380     nullptr,
381     nullptr,
382     nullptr,
383    },
384    {"s11",
385     nullptr,
386     4,
387     0,
388     eEncodingIEEE754,
389     eFormatFloat,
390     {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391      LLDB_INVALID_REGNUM},
392     nullptr,
393     nullptr,
394     nullptr,
395    },
396    {"s12",
397     nullptr,
398     4,
399     0,
400     eEncodingIEEE754,
401     eFormatFloat,
402     {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
403      LLDB_INVALID_REGNUM},
404     nullptr,
405     nullptr,
406     nullptr,
407    },
408    {"s13",
409     nullptr,
410     4,
411     0,
412     eEncodingIEEE754,
413     eFormatFloat,
414     {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415      LLDB_INVALID_REGNUM},
416     nullptr,
417     nullptr,
418     nullptr,
419    },
420    {"s14",
421     nullptr,
422     4,
423     0,
424     eEncodingIEEE754,
425     eFormatFloat,
426     {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
427      LLDB_INVALID_REGNUM},
428     nullptr,
429     nullptr,
430     nullptr,
431    },
432    {"s15",
433     nullptr,
434     4,
435     0,
436     eEncodingIEEE754,
437     eFormatFloat,
438     {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
439      LLDB_INVALID_REGNUM},
440     nullptr,
441     nullptr,
442     nullptr,
443    },
444    {"s16",
445     nullptr,
446     4,
447     0,
448     eEncodingIEEE754,
449     eFormatFloat,
450     {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
451      LLDB_INVALID_REGNUM},
452     nullptr,
453     nullptr,
454     nullptr,
455    },
456    {"s17",
457     nullptr,
458     4,
459     0,
460     eEncodingIEEE754,
461     eFormatFloat,
462     {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
463      LLDB_INVALID_REGNUM},
464     nullptr,
465     nullptr,
466     nullptr,
467    },
468    {"s18",
469     nullptr,
470     4,
471     0,
472     eEncodingIEEE754,
473     eFormatFloat,
474     {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
475      LLDB_INVALID_REGNUM},
476     nullptr,
477     nullptr,
478     nullptr,
479    },
480    {"s19",
481     nullptr,
482     4,
483     0,
484     eEncodingIEEE754,
485     eFormatFloat,
486     {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
487      LLDB_INVALID_REGNUM},
488     nullptr,
489     nullptr,
490     nullptr,
491    },
492    {"s20",
493     nullptr,
494     4,
495     0,
496     eEncodingIEEE754,
497     eFormatFloat,
498     {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
499      LLDB_INVALID_REGNUM},
500     nullptr,
501     nullptr,
502     nullptr,
503    },
504    {"s21",
505     nullptr,
506     4,
507     0,
508     eEncodingIEEE754,
509     eFormatFloat,
510     {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
511      LLDB_INVALID_REGNUM},
512     nullptr,
513     nullptr,
514     nullptr,
515    },
516    {"s22",
517     nullptr,
518     4,
519     0,
520     eEncodingIEEE754,
521     eFormatFloat,
522     {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523      LLDB_INVALID_REGNUM},
524     nullptr,
525     nullptr,
526     nullptr,
527    },
528    {"s23",
529     nullptr,
530     4,
531     0,
532     eEncodingIEEE754,
533     eFormatFloat,
534     {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
535      LLDB_INVALID_REGNUM},
536     nullptr,
537     nullptr,
538     nullptr,
539    },
540    {"s24",
541     nullptr,
542     4,
543     0,
544     eEncodingIEEE754,
545     eFormatFloat,
546     {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
547      LLDB_INVALID_REGNUM},
548     nullptr,
549     nullptr,
550     nullptr,
551    },
552    {"s25",
553     nullptr,
554     4,
555     0,
556     eEncodingIEEE754,
557     eFormatFloat,
558     {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
559      LLDB_INVALID_REGNUM},
560     nullptr,
561     nullptr,
562     nullptr,
563    },
564    {"s26",
565     nullptr,
566     4,
567     0,
568     eEncodingIEEE754,
569     eFormatFloat,
570     {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
571      LLDB_INVALID_REGNUM},
572     nullptr,
573     nullptr,
574     nullptr,
575    },
576    {"s27",
577     nullptr,
578     4,
579     0,
580     eEncodingIEEE754,
581     eFormatFloat,
582     {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
583      LLDB_INVALID_REGNUM},
584     nullptr,
585     nullptr,
586     nullptr,
587    },
588    {"s28",
589     nullptr,
590     4,
591     0,
592     eEncodingIEEE754,
593     eFormatFloat,
594     {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
595      LLDB_INVALID_REGNUM},
596     nullptr,
597     nullptr,
598     nullptr,
599    },
600    {"s29",
601     nullptr,
602     4,
603     0,
604     eEncodingIEEE754,
605     eFormatFloat,
606     {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
607      LLDB_INVALID_REGNUM},
608     nullptr,
609     nullptr,
610     nullptr,
611    },
612    {"s30",
613     nullptr,
614     4,
615     0,
616     eEncodingIEEE754,
617     eFormatFloat,
618     {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
619      LLDB_INVALID_REGNUM},
620     nullptr,
621     nullptr,
622     nullptr,
623    },
624    {"s31",
625     nullptr,
626     4,
627     0,
628     eEncodingIEEE754,
629     eFormatFloat,
630     {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
631      LLDB_INVALID_REGNUM},
632     nullptr,
633     nullptr,
634     nullptr,
635    },
636    {"fpscr",
637     nullptr,
638     4,
639     0,
640     eEncodingUint,
641     eFormatHex,
642     {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
643      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
644     nullptr,
645     nullptr,
646     nullptr,
647    },
648    {"d0",
649     nullptr,
650     8,
651     0,
652     eEncodingIEEE754,
653     eFormatFloat,
654     {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
655      LLDB_INVALID_REGNUM},
656     nullptr,
657     nullptr,
658     nullptr,
659    },
660    {"d1",
661     nullptr,
662     8,
663     0,
664     eEncodingIEEE754,
665     eFormatFloat,
666     {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
667      LLDB_INVALID_REGNUM},
668     nullptr,
669     nullptr,
670     nullptr,
671    },
672    {"d2",
673     nullptr,
674     8,
675     0,
676     eEncodingIEEE754,
677     eFormatFloat,
678     {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
679      LLDB_INVALID_REGNUM},
680     nullptr,
681     nullptr,
682     nullptr,
683    },
684    {"d3",
685     nullptr,
686     8,
687     0,
688     eEncodingIEEE754,
689     eFormatFloat,
690     {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
691      LLDB_INVALID_REGNUM},
692     nullptr,
693     nullptr,
694     nullptr,
695    },
696    {"d4",
697     nullptr,
698     8,
699     0,
700     eEncodingIEEE754,
701     eFormatFloat,
702     {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
703      LLDB_INVALID_REGNUM},
704     nullptr,
705     nullptr,
706     nullptr,
707    },
708    {"d5",
709     nullptr,
710     8,
711     0,
712     eEncodingIEEE754,
713     eFormatFloat,
714     {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
715      LLDB_INVALID_REGNUM},
716     nullptr,
717     nullptr,
718     nullptr,
719    },
720    {"d6",
721     nullptr,
722     8,
723     0,
724     eEncodingIEEE754,
725     eFormatFloat,
726     {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
727      LLDB_INVALID_REGNUM},
728     nullptr,
729     nullptr,
730     nullptr,
731    },
732    {"d7",
733     nullptr,
734     8,
735     0,
736     eEncodingIEEE754,
737     eFormatFloat,
738     {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
739      LLDB_INVALID_REGNUM},
740     nullptr,
741     nullptr,
742     nullptr,
743    },
744    {"d8",
745     nullptr,
746     8,
747     0,
748     eEncodingIEEE754,
749     eFormatFloat,
750     {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
751      LLDB_INVALID_REGNUM},
752     nullptr,
753     nullptr,
754     nullptr,
755    },
756    {"d9",
757     nullptr,
758     8,
759     0,
760     eEncodingIEEE754,
761     eFormatFloat,
762     {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
763      LLDB_INVALID_REGNUM},
764     nullptr,
765     nullptr,
766     nullptr,
767    },
768    {"d10",
769     nullptr,
770     8,
771     0,
772     eEncodingIEEE754,
773     eFormatFloat,
774     {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
775      LLDB_INVALID_REGNUM},
776     nullptr,
777     nullptr,
778     nullptr,
779    },
780    {"d11",
781     nullptr,
782     8,
783     0,
784     eEncodingIEEE754,
785     eFormatFloat,
786     {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
787      LLDB_INVALID_REGNUM},
788     nullptr,
789     nullptr,
790     nullptr,
791    },
792    {"d12",
793     nullptr,
794     8,
795     0,
796     eEncodingIEEE754,
797     eFormatFloat,
798     {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
799      LLDB_INVALID_REGNUM},
800     nullptr,
801     nullptr,
802     nullptr,
803    },
804    {"d13",
805     nullptr,
806     8,
807     0,
808     eEncodingIEEE754,
809     eFormatFloat,
810     {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
811      LLDB_INVALID_REGNUM},
812     nullptr,
813     nullptr,
814     nullptr,
815    },
816    {"d14",
817     nullptr,
818     8,
819     0,
820     eEncodingIEEE754,
821     eFormatFloat,
822     {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
823      LLDB_INVALID_REGNUM},
824     nullptr,
825     nullptr,
826     nullptr,
827    },
828    {"d15",
829     nullptr,
830     8,
831     0,
832     eEncodingIEEE754,
833     eFormatFloat,
834     {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
835      LLDB_INVALID_REGNUM},
836     nullptr,
837     nullptr,
838     nullptr,
839    },
840    {"d16",
841     nullptr,
842     8,
843     0,
844     eEncodingIEEE754,
845     eFormatFloat,
846     {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
847      LLDB_INVALID_REGNUM},
848     nullptr,
849     nullptr,
850     nullptr,
851    },
852    {"d17",
853     nullptr,
854     8,
855     0,
856     eEncodingIEEE754,
857     eFormatFloat,
858     {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
859      LLDB_INVALID_REGNUM},
860     nullptr,
861     nullptr,
862     nullptr,
863    },
864    {"d18",
865     nullptr,
866     8,
867     0,
868     eEncodingIEEE754,
869     eFormatFloat,
870     {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
871      LLDB_INVALID_REGNUM},
872     nullptr,
873     nullptr,
874     nullptr,
875    },
876    {"d19",
877     nullptr,
878     8,
879     0,
880     eEncodingIEEE754,
881     eFormatFloat,
882     {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
883      LLDB_INVALID_REGNUM},
884     nullptr,
885     nullptr,
886     nullptr,
887    },
888    {"d20",
889     nullptr,
890     8,
891     0,
892     eEncodingIEEE754,
893     eFormatFloat,
894     {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
895      LLDB_INVALID_REGNUM},
896     nullptr,
897     nullptr,
898     nullptr,
899    },
900    {"d21",
901     nullptr,
902     8,
903     0,
904     eEncodingIEEE754,
905     eFormatFloat,
906     {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
907      LLDB_INVALID_REGNUM},
908     nullptr,
909     nullptr,
910     nullptr,
911    },
912    {"d22",
913     nullptr,
914     8,
915     0,
916     eEncodingIEEE754,
917     eFormatFloat,
918     {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
919      LLDB_INVALID_REGNUM},
920     nullptr,
921     nullptr,
922     nullptr,
923    },
924    {"d23",
925     nullptr,
926     8,
927     0,
928     eEncodingIEEE754,
929     eFormatFloat,
930     {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
931      LLDB_INVALID_REGNUM},
932     nullptr,
933     nullptr,
934     nullptr,
935    },
936    {"d24",
937     nullptr,
938     8,
939     0,
940     eEncodingIEEE754,
941     eFormatFloat,
942     {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
943      LLDB_INVALID_REGNUM},
944     nullptr,
945     nullptr,
946     nullptr,
947    },
948    {"d25",
949     nullptr,
950     8,
951     0,
952     eEncodingIEEE754,
953     eFormatFloat,
954     {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
955      LLDB_INVALID_REGNUM},
956     nullptr,
957     nullptr,
958     nullptr,
959    },
960    {"d26",
961     nullptr,
962     8,
963     0,
964     eEncodingIEEE754,
965     eFormatFloat,
966     {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
967      LLDB_INVALID_REGNUM},
968     nullptr,
969     nullptr,
970     nullptr,
971    },
972    {"d27",
973     nullptr,
974     8,
975     0,
976     eEncodingIEEE754,
977     eFormatFloat,
978     {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
979      LLDB_INVALID_REGNUM},
980     nullptr,
981     nullptr,
982     nullptr,
983    },
984    {"d28",
985     nullptr,
986     8,
987     0,
988     eEncodingIEEE754,
989     eFormatFloat,
990     {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
991      LLDB_INVALID_REGNUM},
992     nullptr,
993     nullptr,
994     nullptr,
995    },
996    {"d29",
997     nullptr,
998     8,
999     0,
1000     eEncodingIEEE754,
1001     eFormatFloat,
1002     {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1003      LLDB_INVALID_REGNUM},
1004     nullptr,
1005     nullptr,
1006     nullptr,
1007    },
1008    {"d30",
1009     nullptr,
1010     8,
1011     0,
1012     eEncodingIEEE754,
1013     eFormatFloat,
1014     {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1015      LLDB_INVALID_REGNUM},
1016     nullptr,
1017     nullptr,
1018     nullptr,
1019    },
1020    {"d31",
1021     nullptr,
1022     8,
1023     0,
1024     eEncodingIEEE754,
1025     eFormatFloat,
1026     {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1027      LLDB_INVALID_REGNUM},
1028     nullptr,
1029     nullptr,
1030     nullptr,
1031    },
1032    {"r8_usr",
1033     nullptr,
1034     4,
1035     0,
1036     eEncodingUint,
1037     eFormatHex,
1038     {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1039      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1040     nullptr,
1041     nullptr,
1042     nullptr,
1043    },
1044    {"r9_usr",
1045     nullptr,
1046     4,
1047     0,
1048     eEncodingUint,
1049     eFormatHex,
1050     {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1051      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1052     nullptr,
1053     nullptr,
1054     nullptr,
1055    },
1056    {"r10_usr",
1057     nullptr,
1058     4,
1059     0,
1060     eEncodingUint,
1061     eFormatHex,
1062     {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1063      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1064     nullptr,
1065     nullptr,
1066     nullptr,
1067    },
1068    {"r11_usr",
1069     nullptr,
1070     4,
1071     0,
1072     eEncodingUint,
1073     eFormatHex,
1074     {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1075      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1076     nullptr,
1077     nullptr,
1078     nullptr,
1079    },
1080    {"r12_usr",
1081     nullptr,
1082     4,
1083     0,
1084     eEncodingUint,
1085     eFormatHex,
1086     {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1087      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1088     nullptr,
1089     nullptr,
1090     nullptr,
1091    },
1092    {"r13_usr",
1093     "sp_usr",
1094     4,
1095     0,
1096     eEncodingUint,
1097     eFormatHex,
1098     {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1099      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1100     nullptr,
1101     nullptr,
1102     nullptr,
1103    },
1104    {"r14_usr",
1105     "lr_usr",
1106     4,
1107     0,
1108     eEncodingUint,
1109     eFormatHex,
1110     {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1111      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1112     nullptr,
1113     nullptr,
1114     nullptr,
1115    },
1116    {"r8_fiq",
1117     nullptr,
1118     4,
1119     0,
1120     eEncodingUint,
1121     eFormatHex,
1122     {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1123      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1124     nullptr,
1125     nullptr,
1126     nullptr,
1127    },
1128    {"r9_fiq",
1129     nullptr,
1130     4,
1131     0,
1132     eEncodingUint,
1133     eFormatHex,
1134     {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1135      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1136     nullptr,
1137     nullptr,
1138     nullptr,
1139    },
1140    {"r10_fiq",
1141     nullptr,
1142     4,
1143     0,
1144     eEncodingUint,
1145     eFormatHex,
1146     {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1147      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1148     nullptr,
1149     nullptr,
1150     nullptr,
1151    },
1152    {"r11_fiq",
1153     nullptr,
1154     4,
1155     0,
1156     eEncodingUint,
1157     eFormatHex,
1158     {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1159      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1160     nullptr,
1161     nullptr,
1162     nullptr,
1163    },
1164    {"r12_fiq",
1165     nullptr,
1166     4,
1167     0,
1168     eEncodingUint,
1169     eFormatHex,
1170     {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1171      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1172     nullptr,
1173     nullptr,
1174     nullptr,
1175    },
1176    {"r13_fiq",
1177     "sp_fiq",
1178     4,
1179     0,
1180     eEncodingUint,
1181     eFormatHex,
1182     {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1183      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1184     nullptr,
1185     nullptr,
1186     nullptr,
1187    },
1188    {"r14_fiq",
1189     "lr_fiq",
1190     4,
1191     0,
1192     eEncodingUint,
1193     eFormatHex,
1194     {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1195      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1196     nullptr,
1197     nullptr,
1198     nullptr,
1199    },
1200    {"r13_irq",
1201     "sp_irq",
1202     4,
1203     0,
1204     eEncodingUint,
1205     eFormatHex,
1206     {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1207      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1208     nullptr,
1209     nullptr,
1210     nullptr,
1211    },
1212    {"r14_irq",
1213     "lr_irq",
1214     4,
1215     0,
1216     eEncodingUint,
1217     eFormatHex,
1218     {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1219      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1220     nullptr,
1221     nullptr,
1222     nullptr,
1223    },
1224    {"r13_abt",
1225     "sp_abt",
1226     4,
1227     0,
1228     eEncodingUint,
1229     eFormatHex,
1230     {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1231      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1232     nullptr,
1233     nullptr,
1234     nullptr,
1235    },
1236    {"r14_abt",
1237     "lr_abt",
1238     4,
1239     0,
1240     eEncodingUint,
1241     eFormatHex,
1242     {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1243      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1244     nullptr,
1245     nullptr,
1246     nullptr,
1247    },
1248    {"r13_und",
1249     "sp_und",
1250     4,
1251     0,
1252     eEncodingUint,
1253     eFormatHex,
1254     {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1255      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1256     nullptr,
1257     nullptr,
1258     nullptr,
1259    },
1260    {"r14_und",
1261     "lr_und",
1262     4,
1263     0,
1264     eEncodingUint,
1265     eFormatHex,
1266     {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1267      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1268     nullptr,
1269     nullptr,
1270     nullptr,
1271
1272    },
1273    {"r13_svc",
1274     "sp_svc",
1275     4,
1276     0,
1277     eEncodingUint,
1278     eFormatHex,
1279     {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1280      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1281     nullptr,
1282     nullptr,
1283     nullptr,
1284    },
1285    {"r14_svc",
1286     "lr_svc",
1287     4,
1288     0,
1289     eEncodingUint,
1290     eFormatHex,
1291     {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1292      LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1293     nullptr,
1294     nullptr,
1295     nullptr,
1296     }};
1297
1298static const uint32_t k_num_register_infos = std::size(g_register_infos);
1299
1300const lldb_private::RegisterInfo *
1301ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
1302  count = k_num_register_infos;
1303  return g_register_infos;
1304}
1305
1306size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1307
1308// Static Functions
1309
1310ABISP
1311ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1312  const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1313  const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1314
1315  if (vendor_type != llvm::Triple::Apple) {
1316    if ((arch_type == llvm::Triple::arm) ||
1317        (arch_type == llvm::Triple::thumb)) {
1318      return ABISP(
1319          new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1320    }
1321  }
1322
1323  return ABISP();
1324}
1325
1326bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1327                                     addr_t function_addr, addr_t return_addr,
1328                                     llvm::ArrayRef<addr_t> args) const {
1329  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1330  if (!reg_ctx)
1331    return false;
1332
1333  const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1334      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1335  const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1336      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1337  const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1338      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1339
1340  RegisterValue reg_value;
1341
1342  const uint8_t reg_names[] = {
1343      LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
1344      LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
1345
1346  llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1347
1348  for (size_t i = 0; i < std::size(reg_names); ++i) {
1349    if (ai == ae)
1350      break;
1351
1352    reg_value.SetUInt32(*ai);
1353    if (!reg_ctx->WriteRegister(
1354            reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1355            reg_value))
1356      return false;
1357
1358    ++ai;
1359  }
1360
1361  if (ai != ae) {
1362    // Spill onto the stack
1363    size_t num_stack_regs = ae - ai;
1364
1365    sp -= (num_stack_regs * 4);
1366    // Keep the stack 8 byte aligned, not that we need to
1367    sp &= ~(8ull - 1ull);
1368
1369    // just using arg1 to get the right size
1370    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1371        eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1372
1373    addr_t arg_pos = sp;
1374
1375    for (; ai != ae; ++ai) {
1376      reg_value.SetUInt32(*ai);
1377      if (reg_ctx
1378              ->WriteRegisterValueToMemory(reg_info, arg_pos,
1379                                           reg_info->byte_size, reg_value)
1380              .Fail())
1381        return false;
1382      arg_pos += reg_info->byte_size;
1383    }
1384  }
1385
1386  TargetSP target_sp(thread.CalculateTarget());
1387  Address so_addr;
1388
1389  // Figure out if our return address is ARM or Thumb by using the
1390  // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1391  // thumb-ness and set the correct address bits for us.
1392  so_addr.SetLoadAddress(return_addr, target_sp.get());
1393  return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1394
1395  // Set "lr" to the return address
1396  if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1397    return false;
1398
1399  // Set "sp" to the requested value
1400  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1401    return false;
1402
1403  // If bit zero or 1 is set, this must be a thumb function, no need to figure
1404  // this out from the symbols.
1405  so_addr.SetLoadAddress(function_addr, target_sp.get());
1406  function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1407
1408  const RegisterInfo *cpsr_reg_info =
1409      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
1410  const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1411
1412  // Make a new CPSR and mask out any Thumb IT (if/then) bits
1413  uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1414  // If bit zero or 1 is set, this must be thumb...
1415  if (function_addr & 1ull)
1416    new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1417  else
1418    new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1419
1420  if (new_cpsr != curr_cpsr) {
1421    if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1422      return false;
1423  }
1424
1425  function_addr &=
1426      ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1427
1428  // Set "pc" to the address requested
1429  return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1430}
1431
1432bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1433  uint32_t num_values = values.GetSize();
1434
1435  ExecutionContext exe_ctx(thread.shared_from_this());
1436  // For now, assume that the types in the AST values come from the Target's
1437  // scratch AST.
1438
1439  // Extract the register context so we can read arguments from registers
1440
1441  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1442
1443  if (!reg_ctx)
1444    return false;
1445
1446  addr_t sp = 0;
1447
1448  for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1449    // We currently only support extracting values with Clang QualTypes. Do we
1450    // care about others?
1451    Value *value = values.GetValueAtIndex(value_idx);
1452
1453    if (!value)
1454      return false;
1455
1456    CompilerType compiler_type = value->GetCompilerType();
1457    if (compiler_type) {
1458      bool is_signed = false;
1459      size_t bit_width = 0;
1460      if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1461          compiler_type.IsPointerOrReferenceType()) {
1462        if (std::optional<uint64_t> size = compiler_type.GetBitSize(&thread))
1463          bit_width = *size;
1464      } else {
1465        // We only handle integer, pointer and reference types currently...
1466        return false;
1467      }
1468
1469      if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1470        if (value_idx < 4) {
1471          // Arguments 1-4 are in r0-r3...
1472          const RegisterInfo *arg_reg_info = nullptr;
1473          arg_reg_info = reg_ctx->GetRegisterInfo(
1474              eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1475          if (arg_reg_info) {
1476            RegisterValue reg_value;
1477
1478            if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1479              if (is_signed)
1480                reg_value.SignExtend(bit_width);
1481              if (!reg_value.GetScalarValue(value->GetScalar()))
1482                return false;
1483              continue;
1484            }
1485          }
1486          return false;
1487        } else {
1488          if (sp == 0) {
1489            // Read the stack pointer if it already hasn't been read
1490            sp = reg_ctx->GetSP(0);
1491            if (sp == 0)
1492              return false;
1493          }
1494
1495          // Arguments 5 on up are on the stack
1496          const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1497          Status error;
1498          if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1499                  sp, arg_byte_size, is_signed, value->GetScalar(), error))
1500            return false;
1501
1502          sp += arg_byte_size;
1503        }
1504      }
1505    }
1506  }
1507  return true;
1508}
1509
1510static bool GetReturnValuePassedInMemory(Thread &thread,
1511                                         RegisterContext *reg_ctx,
1512                                         size_t byte_size, Value &value) {
1513  Status error;
1514  DataBufferHeap buffer(byte_size, 0);
1515
1516  const RegisterInfo *r0_reg_info =
1517      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1518  uint32_t address =
1519      reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1520  thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1521                                  buffer.GetByteSize(), error);
1522
1523  if (error.Fail())
1524    return false;
1525
1526  value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1527  return true;
1528}
1529
1530bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
1531  ProcessSP process_sp(thread.GetProcess());
1532  if (process_sp) {
1533    const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1534
1535    return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1536  }
1537
1538  return false;
1539}
1540
1541ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
1542    Thread &thread, lldb_private::CompilerType &compiler_type) const {
1543  Value value;
1544  ValueObjectSP return_valobj_sp;
1545
1546  if (!compiler_type)
1547    return return_valobj_sp;
1548
1549  // value.SetContext (Value::eContextTypeClangType,
1550  // compiler_type.GetOpaqueQualType());
1551  value.SetCompilerType(compiler_type);
1552
1553  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1554  if (!reg_ctx)
1555    return return_valobj_sp;
1556
1557  bool is_signed;
1558  bool is_complex;
1559  uint32_t float_count;
1560  bool is_vfp_candidate = false;
1561  uint8_t vfp_count = 0;
1562  uint8_t vfp_byte_size = 0;
1563
1564  // Get the pointer to the first stack argument so we have a place to start
1565  // when reading data
1566
1567  const RegisterInfo *r0_reg_info =
1568      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1569  std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1570  std::optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1571  if (!bit_width || !byte_size)
1572    return return_valobj_sp;
1573
1574  if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1575    switch (*bit_width) {
1576    default:
1577      return return_valobj_sp;
1578    case 64: {
1579      const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1580          eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1581      uint64_t raw_value;
1582      raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1583      raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1584                               UINT32_MAX))
1585                   << 32;
1586      if (is_signed)
1587        value.GetScalar() = (int64_t)raw_value;
1588      else
1589        value.GetScalar() = (uint64_t)raw_value;
1590    } break;
1591    case 32:
1592      if (is_signed)
1593        value.GetScalar() = (int32_t)(
1594            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1595      else
1596        value.GetScalar() = (uint32_t)(
1597            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1598      break;
1599    case 16:
1600      if (is_signed)
1601        value.GetScalar() = (int16_t)(
1602            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1603      else
1604        value.GetScalar() = (uint16_t)(
1605            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1606      break;
1607    case 8:
1608      if (is_signed)
1609        value.GetScalar() = (int8_t)(
1610            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1611      else
1612        value.GetScalar() = (uint8_t)(
1613            reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1614      break;
1615    }
1616  } else if (compiler_type.IsPointerType()) {
1617    uint32_t ptr =
1618        thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1619        UINT32_MAX;
1620    value.GetScalar() = ptr;
1621  } else if (compiler_type.IsVectorType()) {
1622    if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1623      is_vfp_candidate = true;
1624      vfp_byte_size = 8;
1625      vfp_count = (*byte_size == 8 ? 1 : 2);
1626    } else if (*byte_size <= 16) {
1627      DataBufferHeap buffer(16, 0);
1628      uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1629
1630      for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1631        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1632            eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
1633        buffer_ptr[i] =
1634            reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1635      }
1636      value.SetBytes(buffer.GetBytes(), *byte_size);
1637    } else {
1638      if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1639        return return_valobj_sp;
1640    }
1641  } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1642    if (float_count == 1 && !is_complex) {
1643      switch (*bit_width) {
1644      default:
1645        return return_valobj_sp;
1646      case 64: {
1647        static_assert(sizeof(double) == sizeof(uint64_t));
1648
1649        if (IsArmHardFloat(thread)) {
1650          RegisterValue reg_value;
1651          const RegisterInfo *d0_reg_info =
1652              reg_ctx->GetRegisterInfoByName("d0", 0);
1653          reg_ctx->ReadRegister(d0_reg_info, reg_value);
1654          value.GetScalar() = reg_value.GetAsDouble();
1655        } else {
1656          uint64_t raw_value;
1657          const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1658              eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1659          raw_value =
1660              reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1661          raw_value |=
1662              ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1663                          UINT32_MAX))
1664              << 32;
1665          value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1666        }
1667        break;
1668      }
1669      case 16: // Half precision returned after a conversion to single precision
1670      case 32: {
1671        static_assert(sizeof(float) == sizeof(uint32_t));
1672
1673        if (IsArmHardFloat(thread)) {
1674          RegisterValue reg_value;
1675          const RegisterInfo *s0_reg_info =
1676              reg_ctx->GetRegisterInfoByName("s0", 0);
1677          reg_ctx->ReadRegister(s0_reg_info, reg_value);
1678          value.GetScalar() = reg_value.GetAsFloat();
1679        } else {
1680          uint32_t raw_value;
1681          raw_value =
1682              reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1683          value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1684        }
1685        break;
1686      }
1687      }
1688    } else if (is_complex && float_count == 2) {
1689      if (IsArmHardFloat(thread)) {
1690        is_vfp_candidate = true;
1691        vfp_byte_size = *byte_size / 2;
1692        vfp_count = 2;
1693      } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1694                                               value))
1695        return return_valobj_sp;
1696    } else
1697      // not handled yet
1698      return return_valobj_sp;
1699  } else if (compiler_type.IsAggregateType()) {
1700    if (IsArmHardFloat(thread)) {
1701      CompilerType base_type;
1702      const uint32_t homogeneous_count =
1703          compiler_type.IsHomogeneousAggregate(&base_type);
1704
1705      if (homogeneous_count > 0 && homogeneous_count <= 4) {
1706        std::optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread);
1707        if (base_type.IsVectorType()) {
1708          if (base_byte_size &&
1709              (*base_byte_size == 8 || *base_byte_size == 16)) {
1710            is_vfp_candidate = true;
1711            vfp_byte_size = 8;
1712            vfp_count = (*base_byte_size == 8 ? homogeneous_count
1713                                              : homogeneous_count * 2);
1714          }
1715        } else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1716          if (float_count == 1 && !is_complex) {
1717            is_vfp_candidate = true;
1718            if (base_byte_size)
1719              vfp_byte_size = *base_byte_size;
1720            vfp_count = homogeneous_count;
1721          }
1722        }
1723      } else if (homogeneous_count == 0) {
1724        const uint32_t num_children = compiler_type.GetNumFields();
1725
1726        if (num_children > 0 && num_children <= 2) {
1727          uint32_t index = 0;
1728          for (index = 0; index < num_children; index++) {
1729            std::string name;
1730            base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1731                                                      nullptr, nullptr);
1732
1733            if (base_type.IsFloatingPointType(float_count, is_complex)) {
1734              std::optional<uint64_t> base_byte_size =
1735                  base_type.GetByteSize(&thread);
1736              if (float_count == 2 && is_complex) {
1737                if (index != 0 && base_byte_size &&
1738                    vfp_byte_size != *base_byte_size)
1739                  break;
1740                else if (base_byte_size)
1741                  vfp_byte_size = *base_byte_size;
1742              } else
1743                break;
1744            } else
1745              break;
1746          }
1747
1748          if (index == num_children) {
1749            is_vfp_candidate = true;
1750            vfp_byte_size = (vfp_byte_size >> 1);
1751            vfp_count = (num_children << 1);
1752          }
1753        }
1754      }
1755    }
1756
1757    if (*byte_size <= 4) {
1758      RegisterValue r0_reg_value;
1759      uint32_t raw_value =
1760          reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1761      value.SetBytes(&raw_value, *byte_size);
1762    } else if (!is_vfp_candidate) {
1763      if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1764        return return_valobj_sp;
1765    }
1766  } else {
1767    // not handled yet
1768    return return_valobj_sp;
1769  }
1770
1771  if (is_vfp_candidate) {
1772    ProcessSP process_sp(thread.GetProcess());
1773    ByteOrder byte_order = process_sp->GetByteOrder();
1774
1775    WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1776    uint32_t data_offset = 0;
1777
1778    for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1779      uint32_t regnum = 0;
1780
1781      if (vfp_byte_size == 4)
1782        regnum = dwarf_s0 + reg_index;
1783      else if (vfp_byte_size == 8)
1784        regnum = dwarf_d0 + reg_index;
1785      else
1786        break;
1787
1788      const RegisterInfo *reg_info =
1789          reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1790      if (reg_info == nullptr)
1791        break;
1792
1793      RegisterValue reg_value;
1794      if (!reg_ctx->ReadRegister(reg_info, reg_value))
1795        break;
1796
1797      // Make sure we have enough room in "data_sp"
1798      if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1799        Status error;
1800        const size_t bytes_copied = reg_value.GetAsMemoryData(
1801            *reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1802            byte_order, error);
1803        if (bytes_copied != vfp_byte_size)
1804          break;
1805
1806        data_offset += bytes_copied;
1807      }
1808    }
1809
1810    if (data_offset == *byte_size) {
1811      DataExtractor data;
1812      data.SetByteOrder(byte_order);
1813      data.SetAddressByteSize(process_sp->GetAddressByteSize());
1814      data.SetData(data_sp);
1815
1816      return ValueObjectConstResult::Create(&thread, compiler_type,
1817                                            ConstString(""), data);
1818    } else { // Some error occurred while getting values from registers
1819      return return_valobj_sp;
1820    }
1821  }
1822
1823  // If we get here, we have a valid Value, so make our ValueObject out of it:
1824
1825  return_valobj_sp = ValueObjectConstResult::Create(
1826      thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1827  return return_valobj_sp;
1828}
1829
1830Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1831                                         lldb::ValueObjectSP &new_value_sp) {
1832  Status error;
1833  if (!new_value_sp) {
1834    error.SetErrorString("Empty value object for return value.");
1835    return error;
1836  }
1837
1838  CompilerType compiler_type = new_value_sp->GetCompilerType();
1839  if (!compiler_type) {
1840    error.SetErrorString("Null clang type for return value.");
1841    return error;
1842  }
1843
1844  Thread *thread = frame_sp->GetThread().get();
1845
1846  bool is_signed;
1847  uint32_t count;
1848  bool is_complex;
1849
1850  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1851
1852  bool set_it_simple = false;
1853  if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1854      compiler_type.IsPointerType()) {
1855    DataExtractor data;
1856    Status data_error;
1857    size_t num_bytes = new_value_sp->GetData(data, data_error);
1858    if (data_error.Fail()) {
1859      error.SetErrorStringWithFormat(
1860          "Couldn't convert return value to raw data: %s",
1861          data_error.AsCString());
1862      return error;
1863    }
1864    lldb::offset_t offset = 0;
1865    if (num_bytes <= 8) {
1866      const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1867          eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1868      if (num_bytes <= 4) {
1869        uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1870
1871        if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1872          set_it_simple = true;
1873      } else {
1874        uint32_t raw_value = data.GetMaxU32(&offset, 4);
1875
1876        if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1877          const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1878              eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1879          uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1880
1881          if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1882            set_it_simple = true;
1883        }
1884      }
1885    } else {
1886      error.SetErrorString("We don't support returning longer than 64 bit "
1887                           "integer values at present.");
1888    }
1889  } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1890    if (is_complex)
1891      error.SetErrorString(
1892          "We don't support returning complex values at present");
1893    else
1894      error.SetErrorString(
1895          "We don't support returning float values at present");
1896  }
1897
1898  if (!set_it_simple)
1899    error.SetErrorString(
1900        "We only support setting simple integer return types at present.");
1901
1902  return error;
1903}
1904
1905bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1906  unwind_plan.Clear();
1907  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1908
1909  uint32_t lr_reg_num = dwarf_lr;
1910  uint32_t sp_reg_num = dwarf_sp;
1911  uint32_t pc_reg_num = dwarf_pc;
1912
1913  UnwindPlan::RowSP row(new UnwindPlan::Row);
1914
1915  // Our Call Frame Address is the stack pointer value
1916  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1917
1918  // The previous PC is in the LR
1919  row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1920  unwind_plan.AppendRow(row);
1921
1922  // All other registers are the same.
1923
1924  unwind_plan.SetSourceName("arm at-func-entry default");
1925  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1926
1927  return true;
1928}
1929
1930bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1931  unwind_plan.Clear();
1932  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1933
1934  // TODO: Handle thumb
1935  uint32_t fp_reg_num = dwarf_r11;
1936  uint32_t pc_reg_num = dwarf_pc;
1937
1938  UnwindPlan::RowSP row(new UnwindPlan::Row);
1939  const int32_t ptr_size = 4;
1940
1941  row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1942  row->SetOffset(0);
1943  row->SetUnspecifiedRegistersAreUndefined(true);
1944
1945  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1946  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1947
1948  unwind_plan.AppendRow(row);
1949  unwind_plan.SetSourceName("arm default unwind plan");
1950  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1951  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1952  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1953
1954  return true;
1955}
1956
1957// cf. "ARMv6 Function Calling Conventions"
1958
1959// ARMv7 on GNU/Linux general purpose reg rules:
1960//    r0-r3 not preserved  (used for argument passing)
1961//    r4-r11 preserved (v1-v8)
1962//    r12   not presrved
1963//    r13   preserved (stack pointer)
1964//    r14   preserved (link register)
1965//    r15   preserved (pc)
1966//    cpsr  not preserved (different rules for different bits)
1967
1968// ARMv7 VFP register rules:
1969//    d0-d7   not preserved   (aka s0-s15, q0-q3)
1970//    d8-d15  preserved       (aka s16-s31, q4-q7)
1971//    d16-d31 not preserved   (aka q8-q15)
1972
1973bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1974  if (reg_info) {
1975    // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1976    const char *name = reg_info->name;
1977    if (name[0] == 'r') {
1978      switch (name[1]) {
1979      case '0':
1980        return name[2] == '\0'; // r0
1981      case '1':
1982        switch (name[2]) {
1983        case '\0':
1984          return true; // r1
1985        case '2':
1986          return name[3] == '\0'; // r12
1987        default:
1988          break;
1989        }
1990        break;
1991
1992      case '2':
1993        return name[2] == '\0'; // r2
1994      case '3':
1995        return name[2] == '\0'; // r3
1996      default:
1997        break;
1998      }
1999    } else if (name[0] == 'd') {
2000      switch (name[1]) {
2001      case '0':
2002        return name[2] == '\0'; // d0 is volatile
2003
2004      case '1':
2005        switch (name[2]) {
2006        case '\0':
2007          return true; // d1 is volatile
2008        case '6':
2009        case '7':
2010        case '8':
2011        case '9':
2012          return name[3] == '\0'; // d16 - d19 are volatile
2013        default:
2014          break;
2015        }
2016        break;
2017
2018      case '2':
2019        switch (name[2]) {
2020        case '\0':
2021          return true; // d2 is volatile
2022        case '0':
2023        case '1':
2024        case '2':
2025        case '3':
2026        case '4':
2027        case '5':
2028        case '6':
2029        case '7':
2030        case '8':
2031        case '9':
2032          return name[3] == '\0'; // d20 - d29 are volatile
2033        default:
2034          break;
2035        }
2036        break;
2037
2038      case '3':
2039        switch (name[2]) {
2040        case '\0':
2041          return true; // d3 is volatile
2042        case '0':
2043        case '1':
2044          return name[3] == '\0'; // d30 - d31 are volatile
2045        default:
2046          break;
2047        }
2048        break;
2049      case '4':
2050      case '5':
2051      case '6':
2052      case '7':
2053        return name[2] == '\0'; // d4 - d7 are volatile
2054
2055      default:
2056        break;
2057      }
2058    } else if (name[0] == 's') {
2059      switch (name[1]) {
2060      case '0':
2061        return name[2] == '\0'; // s0 is volatile
2062
2063      case '1':
2064        switch (name[2]) {
2065        case '\0':
2066          return true; // s1 is volatile
2067        case '0':
2068        case '1':
2069        case '2':
2070        case '3':
2071        case '4':
2072        case '5':
2073          return name[3] == '\0'; // s10 - s15 are volatile
2074        default:
2075          break;
2076        }
2077        break;
2078
2079      case '2':
2080      case '3':
2081      case '4':
2082      case '5':
2083      case '6':
2084      case '7':
2085      case '8':
2086      case '9':
2087        return name[2] == '\0'; // s2 - s9 are volatile
2088
2089      default:
2090        break;
2091      }
2092    } else if (name[0] == 'q') {
2093      switch (name[1]) {
2094      case '1':
2095        switch (name[2]) {
2096        case '\0':
2097          return true; // q1 is volatile
2098        case '0':
2099        case '1':
2100        case '2':
2101        case '3':
2102        case '4':
2103        case '5':
2104          return true; // q10-q15 are volatile
2105        default:
2106          return false;
2107        }
2108        break;
2109
2110      case '0':
2111      case '2':
2112      case '3':
2113        return name[2] == '\0'; // q0-q3 are volatile
2114      case '8':
2115      case '9':
2116        return name[2] == '\0'; // q8-q9 are volatile
2117      default:
2118        break;
2119      }
2120    } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2121      return true;
2122  }
2123  return false;
2124}
2125
2126void ABISysV_arm::Initialize() {
2127  PluginManager::RegisterPlugin(GetPluginNameStatic(),
2128                                "SysV ABI for arm targets", CreateInstance);
2129}
2130
2131void ABISysV_arm::Terminate() {
2132  PluginManager::UnregisterPlugin(CreateInstance);
2133}
2134