1 //===-- ABISysV_arm.cpp ---------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABISysV_arm.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/TargetParser/Triple.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Utility/ConstString.h"
26 #include "lldb/Utility/RegisterValue.h"
27 #include "lldb/Utility/Scalar.h"
28 #include "lldb/Utility/Status.h"
29 #include "lldb/ValueObject/ValueObjectConstResult.h"
31 #include "Plugins/Process/Utility/ARMDefines.h"
32 #include "Utility/ARM_DWARF_Registers.h"
33 #include "Utility/ARM_ehframe_Registers.h"
36 using namespace lldb_private
;
38 LLDB_PLUGIN_DEFINE(ABISysV_arm
)
40 static const RegisterInfo g_register_infos
[] = {
47 {ehframe_r0
, dwarf_r0
, LLDB_REGNUM_GENERIC_ARG1
, LLDB_INVALID_REGNUM
,
59 {ehframe_r1
, dwarf_r1
, LLDB_REGNUM_GENERIC_ARG2
, LLDB_INVALID_REGNUM
,
71 {ehframe_r2
, dwarf_r2
, LLDB_REGNUM_GENERIC_ARG3
, LLDB_INVALID_REGNUM
,
83 {ehframe_r3
, dwarf_r3
, LLDB_REGNUM_GENERIC_ARG4
, LLDB_INVALID_REGNUM
,
95 {ehframe_r4
, dwarf_r4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
107 {ehframe_r5
, dwarf_r5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
108 LLDB_INVALID_REGNUM
},
119 {ehframe_r6
, dwarf_r6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
120 LLDB_INVALID_REGNUM
},
131 {ehframe_r7
, dwarf_r7
, LLDB_REGNUM_GENERIC_FP
, LLDB_INVALID_REGNUM
,
132 LLDB_INVALID_REGNUM
},
143 {ehframe_r8
, dwarf_r8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
144 LLDB_INVALID_REGNUM
},
155 {ehframe_r9
, dwarf_r9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
156 LLDB_INVALID_REGNUM
},
167 {ehframe_r10
, dwarf_r10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
168 LLDB_INVALID_REGNUM
},
179 {ehframe_r11
, dwarf_r11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
180 LLDB_INVALID_REGNUM
},
191 {ehframe_r12
, dwarf_r12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
192 LLDB_INVALID_REGNUM
},
203 {ehframe_sp
, dwarf_sp
, LLDB_REGNUM_GENERIC_SP
, LLDB_INVALID_REGNUM
,
204 LLDB_INVALID_REGNUM
},
215 {ehframe_lr
, dwarf_lr
, LLDB_REGNUM_GENERIC_RA
, LLDB_INVALID_REGNUM
,
216 LLDB_INVALID_REGNUM
},
227 {ehframe_pc
, dwarf_pc
, LLDB_REGNUM_GENERIC_PC
, LLDB_INVALID_REGNUM
,
228 LLDB_INVALID_REGNUM
},
239 {ehframe_cpsr
, dwarf_cpsr
, LLDB_REGNUM_GENERIC_FLAGS
, LLDB_INVALID_REGNUM
,
240 LLDB_INVALID_REGNUM
},
251 {LLDB_INVALID_REGNUM
, dwarf_s0
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
252 LLDB_INVALID_REGNUM
},
263 {LLDB_INVALID_REGNUM
, dwarf_s1
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
264 LLDB_INVALID_REGNUM
},
275 {LLDB_INVALID_REGNUM
, dwarf_s2
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
276 LLDB_INVALID_REGNUM
},
287 {LLDB_INVALID_REGNUM
, dwarf_s3
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
288 LLDB_INVALID_REGNUM
},
299 {LLDB_INVALID_REGNUM
, dwarf_s4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
300 LLDB_INVALID_REGNUM
},
311 {LLDB_INVALID_REGNUM
, dwarf_s5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
312 LLDB_INVALID_REGNUM
},
323 {LLDB_INVALID_REGNUM
, dwarf_s6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
324 LLDB_INVALID_REGNUM
},
335 {LLDB_INVALID_REGNUM
, dwarf_s7
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
336 LLDB_INVALID_REGNUM
},
347 {LLDB_INVALID_REGNUM
, dwarf_s8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
348 LLDB_INVALID_REGNUM
},
359 {LLDB_INVALID_REGNUM
, dwarf_s9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
360 LLDB_INVALID_REGNUM
},
371 {LLDB_INVALID_REGNUM
, dwarf_s10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
372 LLDB_INVALID_REGNUM
},
383 {LLDB_INVALID_REGNUM
, dwarf_s11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
384 LLDB_INVALID_REGNUM
},
395 {LLDB_INVALID_REGNUM
, dwarf_s12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
396 LLDB_INVALID_REGNUM
},
407 {LLDB_INVALID_REGNUM
, dwarf_s13
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
408 LLDB_INVALID_REGNUM
},
419 {LLDB_INVALID_REGNUM
, dwarf_s14
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
420 LLDB_INVALID_REGNUM
},
431 {LLDB_INVALID_REGNUM
, dwarf_s15
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
432 LLDB_INVALID_REGNUM
},
443 {LLDB_INVALID_REGNUM
, dwarf_s16
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
444 LLDB_INVALID_REGNUM
},
455 {LLDB_INVALID_REGNUM
, dwarf_s17
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
456 LLDB_INVALID_REGNUM
},
467 {LLDB_INVALID_REGNUM
, dwarf_s18
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
468 LLDB_INVALID_REGNUM
},
479 {LLDB_INVALID_REGNUM
, dwarf_s19
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
480 LLDB_INVALID_REGNUM
},
491 {LLDB_INVALID_REGNUM
, dwarf_s20
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
492 LLDB_INVALID_REGNUM
},
503 {LLDB_INVALID_REGNUM
, dwarf_s21
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
504 LLDB_INVALID_REGNUM
},
515 {LLDB_INVALID_REGNUM
, dwarf_s22
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
516 LLDB_INVALID_REGNUM
},
527 {LLDB_INVALID_REGNUM
, dwarf_s23
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
528 LLDB_INVALID_REGNUM
},
539 {LLDB_INVALID_REGNUM
, dwarf_s24
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
540 LLDB_INVALID_REGNUM
},
551 {LLDB_INVALID_REGNUM
, dwarf_s25
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
552 LLDB_INVALID_REGNUM
},
563 {LLDB_INVALID_REGNUM
, dwarf_s26
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
564 LLDB_INVALID_REGNUM
},
575 {LLDB_INVALID_REGNUM
, dwarf_s27
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
576 LLDB_INVALID_REGNUM
},
587 {LLDB_INVALID_REGNUM
, dwarf_s28
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
588 LLDB_INVALID_REGNUM
},
599 {LLDB_INVALID_REGNUM
, dwarf_s29
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
600 LLDB_INVALID_REGNUM
},
611 {LLDB_INVALID_REGNUM
, dwarf_s30
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
612 LLDB_INVALID_REGNUM
},
623 {LLDB_INVALID_REGNUM
, dwarf_s31
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
624 LLDB_INVALID_REGNUM
},
635 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
636 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
647 {LLDB_INVALID_REGNUM
, dwarf_d0
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
648 LLDB_INVALID_REGNUM
},
659 {LLDB_INVALID_REGNUM
, dwarf_d1
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
660 LLDB_INVALID_REGNUM
},
671 {LLDB_INVALID_REGNUM
, dwarf_d2
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
672 LLDB_INVALID_REGNUM
},
683 {LLDB_INVALID_REGNUM
, dwarf_d3
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
684 LLDB_INVALID_REGNUM
},
695 {LLDB_INVALID_REGNUM
, dwarf_d4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
696 LLDB_INVALID_REGNUM
},
707 {LLDB_INVALID_REGNUM
, dwarf_d5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
708 LLDB_INVALID_REGNUM
},
719 {LLDB_INVALID_REGNUM
, dwarf_d6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
720 LLDB_INVALID_REGNUM
},
731 {LLDB_INVALID_REGNUM
, dwarf_d7
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
732 LLDB_INVALID_REGNUM
},
743 {LLDB_INVALID_REGNUM
, dwarf_d8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
744 LLDB_INVALID_REGNUM
},
755 {LLDB_INVALID_REGNUM
, dwarf_d9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
756 LLDB_INVALID_REGNUM
},
767 {LLDB_INVALID_REGNUM
, dwarf_d10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
768 LLDB_INVALID_REGNUM
},
779 {LLDB_INVALID_REGNUM
, dwarf_d11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
780 LLDB_INVALID_REGNUM
},
791 {LLDB_INVALID_REGNUM
, dwarf_d12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
792 LLDB_INVALID_REGNUM
},
803 {LLDB_INVALID_REGNUM
, dwarf_d13
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
804 LLDB_INVALID_REGNUM
},
815 {LLDB_INVALID_REGNUM
, dwarf_d14
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
816 LLDB_INVALID_REGNUM
},
827 {LLDB_INVALID_REGNUM
, dwarf_d15
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
828 LLDB_INVALID_REGNUM
},
839 {LLDB_INVALID_REGNUM
, dwarf_d16
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
840 LLDB_INVALID_REGNUM
},
851 {LLDB_INVALID_REGNUM
, dwarf_d17
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
852 LLDB_INVALID_REGNUM
},
863 {LLDB_INVALID_REGNUM
, dwarf_d18
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
864 LLDB_INVALID_REGNUM
},
875 {LLDB_INVALID_REGNUM
, dwarf_d19
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
876 LLDB_INVALID_REGNUM
},
887 {LLDB_INVALID_REGNUM
, dwarf_d20
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
888 LLDB_INVALID_REGNUM
},
899 {LLDB_INVALID_REGNUM
, dwarf_d21
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
900 LLDB_INVALID_REGNUM
},
911 {LLDB_INVALID_REGNUM
, dwarf_d22
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
912 LLDB_INVALID_REGNUM
},
923 {LLDB_INVALID_REGNUM
, dwarf_d23
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
924 LLDB_INVALID_REGNUM
},
935 {LLDB_INVALID_REGNUM
, dwarf_d24
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
936 LLDB_INVALID_REGNUM
},
947 {LLDB_INVALID_REGNUM
, dwarf_d25
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
948 LLDB_INVALID_REGNUM
},
959 {LLDB_INVALID_REGNUM
, dwarf_d26
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
960 LLDB_INVALID_REGNUM
},
971 {LLDB_INVALID_REGNUM
, dwarf_d27
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
972 LLDB_INVALID_REGNUM
},
983 {LLDB_INVALID_REGNUM
, dwarf_d28
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
984 LLDB_INVALID_REGNUM
},
995 {LLDB_INVALID_REGNUM
, dwarf_d29
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
996 LLDB_INVALID_REGNUM
},
1007 {LLDB_INVALID_REGNUM
, dwarf_d30
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
1008 LLDB_INVALID_REGNUM
},
1019 {LLDB_INVALID_REGNUM
, dwarf_d31
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
1020 LLDB_INVALID_REGNUM
},
1031 {LLDB_INVALID_REGNUM
, dwarf_r8_usr
, LLDB_INVALID_REGNUM
,
1032 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1043 {LLDB_INVALID_REGNUM
, dwarf_r9_usr
, LLDB_INVALID_REGNUM
,
1044 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1055 {LLDB_INVALID_REGNUM
, dwarf_r10_usr
, LLDB_INVALID_REGNUM
,
1056 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1067 {LLDB_INVALID_REGNUM
, dwarf_r11_usr
, LLDB_INVALID_REGNUM
,
1068 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1079 {LLDB_INVALID_REGNUM
, dwarf_r12_usr
, LLDB_INVALID_REGNUM
,
1080 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1091 {LLDB_INVALID_REGNUM
, dwarf_r13_usr
, LLDB_INVALID_REGNUM
,
1092 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1103 {LLDB_INVALID_REGNUM
, dwarf_r14_usr
, LLDB_INVALID_REGNUM
,
1104 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1115 {LLDB_INVALID_REGNUM
, dwarf_r8_fiq
, LLDB_INVALID_REGNUM
,
1116 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1127 {LLDB_INVALID_REGNUM
, dwarf_r9_fiq
, LLDB_INVALID_REGNUM
,
1128 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1139 {LLDB_INVALID_REGNUM
, dwarf_r10_fiq
, LLDB_INVALID_REGNUM
,
1140 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1151 {LLDB_INVALID_REGNUM
, dwarf_r11_fiq
, LLDB_INVALID_REGNUM
,
1152 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1163 {LLDB_INVALID_REGNUM
, dwarf_r12_fiq
, LLDB_INVALID_REGNUM
,
1164 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1175 {LLDB_INVALID_REGNUM
, dwarf_r13_fiq
, LLDB_INVALID_REGNUM
,
1176 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1187 {LLDB_INVALID_REGNUM
, dwarf_r14_fiq
, LLDB_INVALID_REGNUM
,
1188 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1199 {LLDB_INVALID_REGNUM
, dwarf_r13_irq
, LLDB_INVALID_REGNUM
,
1200 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1211 {LLDB_INVALID_REGNUM
, dwarf_r14_irq
, LLDB_INVALID_REGNUM
,
1212 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1223 {LLDB_INVALID_REGNUM
, dwarf_r13_abt
, LLDB_INVALID_REGNUM
,
1224 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1235 {LLDB_INVALID_REGNUM
, dwarf_r14_abt
, LLDB_INVALID_REGNUM
,
1236 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1247 {LLDB_INVALID_REGNUM
, dwarf_r13_und
, LLDB_INVALID_REGNUM
,
1248 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1259 {LLDB_INVALID_REGNUM
, dwarf_r14_und
, LLDB_INVALID_REGNUM
,
1260 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1272 {LLDB_INVALID_REGNUM
, dwarf_r13_svc
, LLDB_INVALID_REGNUM
,
1273 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1284 {LLDB_INVALID_REGNUM
, dwarf_r14_svc
, LLDB_INVALID_REGNUM
,
1285 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1291 static const uint32_t k_num_register_infos
= std::size(g_register_infos
);
1293 const lldb_private::RegisterInfo
*
1294 ABISysV_arm::GetRegisterInfoArray(uint32_t &count
) {
1295 count
= k_num_register_infos
;
1296 return g_register_infos
;
1299 size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1304 ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp
, const ArchSpec
&arch
) {
1305 const llvm::Triple::ArchType arch_type
= arch
.GetTriple().getArch();
1306 const llvm::Triple::VendorType vendor_type
= arch
.GetTriple().getVendor();
1308 if (vendor_type
!= llvm::Triple::Apple
) {
1309 if ((arch_type
== llvm::Triple::arm
) ||
1310 (arch_type
== llvm::Triple::thumb
)) {
1312 new ABISysV_arm(std::move(process_sp
), MakeMCRegisterInfo(arch
)));
1319 bool ABISysV_arm::PrepareTrivialCall(Thread
&thread
, addr_t sp
,
1320 addr_t function_addr
, addr_t return_addr
,
1321 llvm::ArrayRef
<addr_t
> args
) const {
1322 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1326 const uint32_t pc_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1327 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_PC
);
1328 const uint32_t sp_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1329 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_SP
);
1330 const uint32_t ra_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1331 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_RA
);
1333 RegisterValue reg_value
;
1335 const uint8_t reg_names
[] = {
1336 LLDB_REGNUM_GENERIC_ARG1
, LLDB_REGNUM_GENERIC_ARG2
,
1337 LLDB_REGNUM_GENERIC_ARG3
, LLDB_REGNUM_GENERIC_ARG4
};
1339 llvm::ArrayRef
<addr_t
>::iterator ai
= args
.begin(), ae
= args
.end();
1341 for (size_t i
= 0; i
< std::size(reg_names
); ++i
) {
1345 reg_value
.SetUInt32(*ai
);
1346 if (!reg_ctx
->WriteRegister(
1347 reg_ctx
->GetRegisterInfo(eRegisterKindGeneric
, reg_names
[i
]),
1355 // Spill onto the stack
1356 size_t num_stack_regs
= ae
- ai
;
1358 sp
-= (num_stack_regs
* 4);
1359 // Keep the stack 8 byte aligned, not that we need to
1360 sp
&= ~(8ull - 1ull);
1362 // just using arg1 to get the right size
1363 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfo(
1364 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
);
1366 addr_t arg_pos
= sp
;
1368 for (; ai
!= ae
; ++ai
) {
1369 reg_value
.SetUInt32(*ai
);
1371 ->WriteRegisterValueToMemory(reg_info
, arg_pos
,
1372 reg_info
->byte_size
, reg_value
)
1375 arg_pos
+= reg_info
->byte_size
;
1379 TargetSP
target_sp(thread
.CalculateTarget());
1382 // Figure out if our return address is ARM or Thumb by using the
1383 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1384 // thumb-ness and set the correct address bits for us.
1385 so_addr
.SetLoadAddress(return_addr
, target_sp
.get());
1386 return_addr
= so_addr
.GetCallableLoadAddress(target_sp
.get());
1388 // Set "lr" to the return address
1389 if (!reg_ctx
->WriteRegisterFromUnsigned(ra_reg_num
, return_addr
))
1392 // Set "sp" to the requested value
1393 if (!reg_ctx
->WriteRegisterFromUnsigned(sp_reg_num
, sp
))
1396 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1397 // this out from the symbols.
1398 so_addr
.SetLoadAddress(function_addr
, target_sp
.get());
1399 function_addr
= so_addr
.GetCallableLoadAddress(target_sp
.get());
1401 const RegisterInfo
*cpsr_reg_info
=
1402 reg_ctx
->GetRegisterInfo(eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_FLAGS
);
1403 const uint32_t curr_cpsr
= reg_ctx
->ReadRegisterAsUnsigned(cpsr_reg_info
, 0);
1405 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1406 uint32_t new_cpsr
= curr_cpsr
& ~MASK_CPSR_IT_MASK
;
1407 // If bit zero or 1 is set, this must be thumb...
1408 if (function_addr
& 1ull)
1409 new_cpsr
|= MASK_CPSR_T
; // Set T bit in CPSR
1411 new_cpsr
&= ~MASK_CPSR_T
; // Clear T bit in CPSR
1413 if (new_cpsr
!= curr_cpsr
) {
1414 if (!reg_ctx
->WriteRegisterFromUnsigned(cpsr_reg_info
, new_cpsr
))
1419 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1421 // Set "pc" to the address requested
1422 return reg_ctx
->WriteRegisterFromUnsigned(pc_reg_num
, function_addr
);
1425 bool ABISysV_arm::GetArgumentValues(Thread
&thread
, ValueList
&values
) const {
1426 uint32_t num_values
= values
.GetSize();
1428 ExecutionContext
exe_ctx(thread
.shared_from_this());
1429 // For now, assume that the types in the AST values come from the Target's
1432 // Extract the register context so we can read arguments from registers
1434 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1441 for (uint32_t value_idx
= 0; value_idx
< num_values
; ++value_idx
) {
1442 // We currently only support extracting values with Clang QualTypes. Do we
1443 // care about others?
1444 Value
*value
= values
.GetValueAtIndex(value_idx
);
1449 CompilerType compiler_type
= value
->GetCompilerType();
1450 if (compiler_type
) {
1451 bool is_signed
= false;
1452 size_t bit_width
= 0;
1453 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
) ||
1454 compiler_type
.IsPointerOrReferenceType()) {
1455 if (std::optional
<uint64_t> size
= compiler_type
.GetBitSize(&thread
))
1458 // We only handle integer, pointer and reference types currently...
1462 if (bit_width
<= (exe_ctx
.GetProcessRef().GetAddressByteSize() * 8)) {
1463 if (value_idx
< 4) {
1464 // Arguments 1-4 are in r0-r3...
1465 const RegisterInfo
*arg_reg_info
= nullptr;
1466 arg_reg_info
= reg_ctx
->GetRegisterInfo(
1467 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
+ value_idx
);
1469 RegisterValue reg_value
;
1471 if (reg_ctx
->ReadRegister(arg_reg_info
, reg_value
)) {
1473 reg_value
.SignExtend(bit_width
);
1474 if (!reg_value
.GetScalarValue(value
->GetScalar()))
1482 // Read the stack pointer if it already hasn't been read
1483 sp
= reg_ctx
->GetSP(0);
1488 // Arguments 5 on up are on the stack
1489 const uint32_t arg_byte_size
= (bit_width
+ (8 - 1)) / 8;
1491 if (!exe_ctx
.GetProcessRef().ReadScalarIntegerFromMemory(
1492 sp
, arg_byte_size
, is_signed
, value
->GetScalar(), error
))
1495 sp
+= arg_byte_size
;
1503 static bool GetReturnValuePassedInMemory(Thread
&thread
,
1504 RegisterContext
*reg_ctx
,
1505 size_t byte_size
, Value
&value
) {
1507 DataBufferHeap
buffer(byte_size
, 0);
1509 const RegisterInfo
*r0_reg_info
=
1510 reg_ctx
->GetRegisterInfo(eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
);
1512 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1513 thread
.GetProcess()->ReadMemory(address
, buffer
.GetBytes(),
1514 buffer
.GetByteSize(), error
);
1519 value
.SetBytes(buffer
.GetBytes(), buffer
.GetByteSize());
1523 bool ABISysV_arm::IsArmHardFloat(Thread
&thread
) const {
1524 ProcessSP
process_sp(thread
.GetProcess());
1526 const ArchSpec
&arch(process_sp
->GetTarget().GetArchitecture());
1528 return (arch
.GetFlags() & ArchSpec::eARM_abi_hard_float
) != 0;
1534 ValueObjectSP
ABISysV_arm::GetReturnValueObjectImpl(
1535 Thread
&thread
, lldb_private::CompilerType
&compiler_type
) const {
1537 ValueObjectSP return_valobj_sp
;
1540 return return_valobj_sp
;
1542 // value.SetContext (Value::eContextTypeClangType,
1543 // compiler_type.GetOpaqueQualType());
1544 value
.SetCompilerType(compiler_type
);
1546 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1548 return return_valobj_sp
;
1552 uint32_t float_count
;
1553 bool is_vfp_candidate
= false;
1554 uint8_t vfp_count
= 0;
1555 uint8_t vfp_byte_size
= 0;
1557 // Get the pointer to the first stack argument so we have a place to start
1558 // when reading data
1560 const RegisterInfo
*r0_reg_info
=
1561 reg_ctx
->GetRegisterInfo(eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
);
1562 std::optional
<uint64_t> bit_width
= compiler_type
.GetBitSize(&thread
);
1563 std::optional
<uint64_t> byte_size
= compiler_type
.GetByteSize(&thread
);
1564 if (!bit_width
|| !byte_size
)
1565 return return_valobj_sp
;
1567 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
)) {
1568 switch (*bit_width
) {
1570 return return_valobj_sp
;
1572 const RegisterInfo
*r1_reg_info
= reg_ctx
->GetRegisterInfo(
1573 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG2
);
1575 raw_value
= reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1576 raw_value
|= ((uint64_t)(reg_ctx
->ReadRegisterAsUnsigned(r1_reg_info
, 0) &
1580 value
.GetScalar() = (int64_t)raw_value
;
1582 value
.GetScalar() = (uint64_t)raw_value
;
1586 value
.GetScalar() = (int32_t)(
1587 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
);
1589 value
.GetScalar() = (uint32_t)(
1590 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
);
1594 value
.GetScalar() = (int16_t)(
1595 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT16_MAX
);
1597 value
.GetScalar() = (uint16_t)(
1598 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT16_MAX
);
1602 value
.GetScalar() = (int8_t)(
1603 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT8_MAX
);
1605 value
.GetScalar() = (uint8_t)(
1606 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT8_MAX
);
1609 } else if (compiler_type
.IsPointerType()) {
1611 thread
.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info
, 0) &
1613 value
.GetScalar() = ptr
;
1614 } else if (compiler_type
.IsVectorType()) {
1615 if (IsArmHardFloat(thread
) && (*byte_size
== 8 || *byte_size
== 16)) {
1616 is_vfp_candidate
= true;
1618 vfp_count
= (*byte_size
== 8 ? 1 : 2);
1619 } else if (*byte_size
<= 16) {
1620 DataBufferHeap
buffer(16, 0);
1621 uint32_t *buffer_ptr
= (uint32_t *)buffer
.GetBytes();
1623 for (uint32_t i
= 0; 4 * i
< *byte_size
; ++i
) {
1624 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfo(
1625 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
+ i
);
1627 reg_ctx
->ReadRegisterAsUnsigned(reg_info
, 0) & UINT32_MAX
;
1629 value
.SetBytes(buffer
.GetBytes(), *byte_size
);
1631 if (!GetReturnValuePassedInMemory(thread
, reg_ctx
, *byte_size
, value
))
1632 return return_valobj_sp
;
1634 } else if (compiler_type
.IsFloatingPointType(float_count
, is_complex
)) {
1635 if (float_count
== 1 && !is_complex
) {
1636 switch (*bit_width
) {
1638 return return_valobj_sp
;
1640 static_assert(sizeof(double) == sizeof(uint64_t));
1642 if (IsArmHardFloat(thread
)) {
1643 RegisterValue reg_value
;
1644 const RegisterInfo
*d0_reg_info
=
1645 reg_ctx
->GetRegisterInfoByName("d0", 0);
1646 reg_ctx
->ReadRegister(d0_reg_info
, reg_value
);
1647 value
.GetScalar() = reg_value
.GetAsDouble();
1650 const RegisterInfo
*r1_reg_info
= reg_ctx
->GetRegisterInfo(
1651 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG2
);
1653 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1655 ((uint64_t)(reg_ctx
->ReadRegisterAsUnsigned(r1_reg_info
, 0) &
1658 value
.GetScalar() = *reinterpret_cast<double *>(&raw_value
);
1662 case 16: // Half precision returned after a conversion to single precision
1664 static_assert(sizeof(float) == sizeof(uint32_t));
1666 if (IsArmHardFloat(thread
)) {
1667 RegisterValue reg_value
;
1668 const RegisterInfo
*s0_reg_info
=
1669 reg_ctx
->GetRegisterInfoByName("s0", 0);
1670 reg_ctx
->ReadRegister(s0_reg_info
, reg_value
);
1671 value
.GetScalar() = reg_value
.GetAsFloat();
1675 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1676 value
.GetScalar() = *reinterpret_cast<float *>(&raw_value
);
1681 } else if (is_complex
&& float_count
== 2) {
1682 if (IsArmHardFloat(thread
)) {
1683 is_vfp_candidate
= true;
1684 vfp_byte_size
= *byte_size
/ 2;
1686 } else if (!GetReturnValuePassedInMemory(thread
, reg_ctx
, *bit_width
/ 8,
1688 return return_valobj_sp
;
1691 return return_valobj_sp
;
1692 } else if (compiler_type
.IsAggregateType()) {
1693 if (IsArmHardFloat(thread
)) {
1694 CompilerType base_type
;
1695 const uint32_t homogeneous_count
=
1696 compiler_type
.IsHomogeneousAggregate(&base_type
);
1698 if (homogeneous_count
> 0 && homogeneous_count
<= 4) {
1699 std::optional
<uint64_t> base_byte_size
= base_type
.GetByteSize(&thread
);
1700 if (base_type
.IsVectorType()) {
1701 if (base_byte_size
&&
1702 (*base_byte_size
== 8 || *base_byte_size
== 16)) {
1703 is_vfp_candidate
= true;
1705 vfp_count
= (*base_byte_size
== 8 ? homogeneous_count
1706 : homogeneous_count
* 2);
1708 } else if (base_type
.IsFloatingPointType(float_count
, is_complex
)) {
1709 if (float_count
== 1 && !is_complex
) {
1710 is_vfp_candidate
= true;
1712 vfp_byte_size
= *base_byte_size
;
1713 vfp_count
= homogeneous_count
;
1716 } else if (homogeneous_count
== 0) {
1717 const uint32_t num_children
= compiler_type
.GetNumFields();
1719 if (num_children
> 0 && num_children
<= 2) {
1721 for (index
= 0; index
< num_children
; index
++) {
1723 base_type
= compiler_type
.GetFieldAtIndex(index
, name
, nullptr,
1726 if (base_type
.IsFloatingPointType(float_count
, is_complex
)) {
1727 std::optional
<uint64_t> base_byte_size
=
1728 base_type
.GetByteSize(&thread
);
1729 if (float_count
== 2 && is_complex
) {
1730 if (index
!= 0 && base_byte_size
&&
1731 vfp_byte_size
!= *base_byte_size
)
1733 else if (base_byte_size
)
1734 vfp_byte_size
= *base_byte_size
;
1741 if (index
== num_children
) {
1742 is_vfp_candidate
= true;
1743 vfp_byte_size
= (vfp_byte_size
>> 1);
1744 vfp_count
= (num_children
<< 1);
1750 if (*byte_size
<= 4) {
1751 RegisterValue r0_reg_value
;
1752 uint32_t raw_value
=
1753 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1754 value
.SetBytes(&raw_value
, *byte_size
);
1755 } else if (!is_vfp_candidate
) {
1756 if (!GetReturnValuePassedInMemory(thread
, reg_ctx
, *byte_size
, value
))
1757 return return_valobj_sp
;
1761 return return_valobj_sp
;
1764 if (is_vfp_candidate
) {
1765 ProcessSP
process_sp(thread
.GetProcess());
1766 ByteOrder byte_order
= process_sp
->GetByteOrder();
1768 WritableDataBufferSP
data_sp(new DataBufferHeap(*byte_size
, 0));
1769 uint32_t data_offset
= 0;
1771 for (uint32_t reg_index
= 0; reg_index
< vfp_count
; reg_index
++) {
1772 uint32_t regnum
= 0;
1774 if (vfp_byte_size
== 4)
1775 regnum
= dwarf_s0
+ reg_index
;
1776 else if (vfp_byte_size
== 8)
1777 regnum
= dwarf_d0
+ reg_index
;
1781 const RegisterInfo
*reg_info
=
1782 reg_ctx
->GetRegisterInfo(eRegisterKindDWARF
, regnum
);
1783 if (reg_info
== nullptr)
1786 RegisterValue reg_value
;
1787 if (!reg_ctx
->ReadRegister(reg_info
, reg_value
))
1790 // Make sure we have enough room in "data_sp"
1791 if ((data_offset
+ vfp_byte_size
) <= data_sp
->GetByteSize()) {
1793 const size_t bytes_copied
= reg_value
.GetAsMemoryData(
1794 *reg_info
, data_sp
->GetBytes() + data_offset
, vfp_byte_size
,
1796 if (bytes_copied
!= vfp_byte_size
)
1799 data_offset
+= bytes_copied
;
1803 if (data_offset
== *byte_size
) {
1805 data
.SetByteOrder(byte_order
);
1806 data
.SetAddressByteSize(process_sp
->GetAddressByteSize());
1807 data
.SetData(data_sp
);
1809 return ValueObjectConstResult::Create(&thread
, compiler_type
,
1810 ConstString(""), data
);
1811 } else { // Some error occurred while getting values from registers
1812 return return_valobj_sp
;
1816 // If we get here, we have a valid Value, so make our ValueObject out of it:
1818 return_valobj_sp
= ValueObjectConstResult::Create(
1819 thread
.GetStackFrameAtIndex(0).get(), value
, ConstString(""));
1820 return return_valobj_sp
;
1823 Status
ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP
&frame_sp
,
1824 lldb::ValueObjectSP
&new_value_sp
) {
1826 if (!new_value_sp
) {
1827 error
= Status::FromErrorString("Empty value object for return value.");
1831 CompilerType compiler_type
= new_value_sp
->GetCompilerType();
1832 if (!compiler_type
) {
1833 error
= Status::FromErrorString("Null clang type for return value.");
1837 Thread
*thread
= frame_sp
->GetThread().get();
1843 RegisterContext
*reg_ctx
= thread
->GetRegisterContext().get();
1845 bool set_it_simple
= false;
1846 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
) ||
1847 compiler_type
.IsPointerType()) {
1850 size_t num_bytes
= new_value_sp
->GetData(data
, data_error
);
1851 if (data_error
.Fail()) {
1852 error
= Status::FromErrorStringWithFormat(
1853 "Couldn't convert return value to raw data: %s",
1854 data_error
.AsCString());
1857 lldb::offset_t offset
= 0;
1858 if (num_bytes
<= 8) {
1859 const RegisterInfo
*r0_info
= reg_ctx
->GetRegisterInfo(
1860 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
);
1861 if (num_bytes
<= 4) {
1862 uint32_t raw_value
= data
.GetMaxU32(&offset
, num_bytes
);
1864 if (reg_ctx
->WriteRegisterFromUnsigned(r0_info
, raw_value
))
1865 set_it_simple
= true;
1867 uint32_t raw_value
= data
.GetMaxU32(&offset
, 4);
1869 if (reg_ctx
->WriteRegisterFromUnsigned(r0_info
, raw_value
)) {
1870 const RegisterInfo
*r1_info
= reg_ctx
->GetRegisterInfo(
1871 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG2
);
1872 uint32_t raw_value
= data
.GetMaxU32(&offset
, num_bytes
- offset
);
1874 if (reg_ctx
->WriteRegisterFromUnsigned(r1_info
, raw_value
))
1875 set_it_simple
= true;
1879 error
= Status::FromErrorString(
1880 "We don't support returning longer than 64 bit "
1881 "integer values at present.");
1883 } else if (compiler_type
.IsFloatingPointType(count
, is_complex
)) {
1885 error
= Status::FromErrorString(
1886 "We don't support returning complex values at present");
1888 error
= Status::FromErrorString(
1889 "We don't support returning float values at present");
1893 error
= Status::FromErrorString(
1894 "We only support setting simple integer return types at present.");
1899 bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan
&unwind_plan
) {
1900 unwind_plan
.Clear();
1901 unwind_plan
.SetRegisterKind(eRegisterKindDWARF
);
1903 uint32_t lr_reg_num
= dwarf_lr
;
1904 uint32_t sp_reg_num
= dwarf_sp
;
1905 uint32_t pc_reg_num
= dwarf_pc
;
1907 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1909 // Our Call Frame Address is the stack pointer value
1910 row
->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num
, 0);
1912 // The previous PC is in the LR
1913 row
->SetRegisterLocationToRegister(pc_reg_num
, lr_reg_num
, true);
1914 unwind_plan
.AppendRow(row
);
1916 // All other registers are the same.
1918 unwind_plan
.SetSourceName("arm at-func-entry default");
1919 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1924 bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan
&unwind_plan
) {
1925 unwind_plan
.Clear();
1926 unwind_plan
.SetRegisterKind(eRegisterKindDWARF
);
1928 // TODO: Handle thumb
1929 uint32_t fp_reg_num
= dwarf_r11
;
1930 uint32_t pc_reg_num
= dwarf_pc
;
1932 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1933 const int32_t ptr_size
= 4;
1935 row
->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num
, 2 * ptr_size
);
1937 row
->SetUnspecifiedRegistersAreUndefined(true);
1939 row
->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num
, ptr_size
* -2, true);
1940 row
->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num
, ptr_size
* -1, true);
1942 unwind_plan
.AppendRow(row
);
1943 unwind_plan
.SetSourceName("arm default unwind plan");
1944 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1945 unwind_plan
.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo
);
1946 unwind_plan
.SetUnwindPlanForSignalTrap(eLazyBoolNo
);
1951 // cf. "ARMv6 Function Calling Conventions"
1953 // ARMv7 on GNU/Linux general purpose reg rules:
1954 // r0-r3 not preserved (used for argument passing)
1955 // r4-r11 preserved (v1-v8)
1957 // r13 preserved (stack pointer)
1958 // r14 preserved (link register)
1959 // r15 preserved (pc)
1960 // cpsr not preserved (different rules for different bits)
1962 // ARMv7 VFP register rules:
1963 // d0-d7 not preserved (aka s0-s15, q0-q3)
1964 // d8-d15 preserved (aka s16-s31, q4-q7)
1965 // d16-d31 not preserved (aka q8-q15)
1967 bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo
*reg_info
) {
1969 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1970 const char *name
= reg_info
->name
;
1971 if (name
[0] == 'r') {
1974 return name
[2] == '\0'; // r0
1980 return name
[3] == '\0'; // r12
1987 return name
[2] == '\0'; // r2
1989 return name
[2] == '\0'; // r3
1993 } else if (name
[0] == 'd') {
1996 return name
[2] == '\0'; // d0 is volatile
2001 return true; // d1 is volatile
2006 return name
[3] == '\0'; // d16 - d19 are volatile
2015 return true; // d2 is volatile
2026 return name
[3] == '\0'; // d20 - d29 are volatile
2035 return true; // d3 is volatile
2038 return name
[3] == '\0'; // d30 - d31 are volatile
2047 return name
[2] == '\0'; // d4 - d7 are volatile
2052 } else if (name
[0] == 's') {
2055 return name
[2] == '\0'; // s0 is volatile
2060 return true; // s1 is volatile
2067 return name
[3] == '\0'; // s10 - s15 are volatile
2081 return name
[2] == '\0'; // s2 - s9 are volatile
2086 } else if (name
[0] == 'q') {
2091 return true; // q1 is volatile
2098 return true; // q10-q15 are volatile
2107 return name
[2] == '\0'; // q0-q3 are volatile
2110 return name
[2] == '\0'; // q8-q9 are volatile
2114 } else if (name
[0] == 's' && name
[1] == 'p' && name
[2] == '\0')
2120 void ABISysV_arm::Initialize() {
2121 PluginManager::RegisterPlugin(GetPluginNameStatic(),
2122 "SysV ABI for arm targets", CreateInstance
);
2125 void ABISysV_arm::Terminate() {
2126 PluginManager::UnregisterPlugin(CreateInstance
);