1 //! Unwind information for System V ABI (Aarch64).
2 
3 use crate::isa::aarch64::inst::regs;
4 use crate::isa::unwind::systemv::RegisterMappingError;
5 use gimli::{write::CommonInformationEntry, Encoding, Format, Register};
6 use regalloc::{Reg, RegClass};
7 
8 /// Creates a new aarch64 common information entry (CIE).
create_cie() -> CommonInformationEntry9 pub fn create_cie() -> CommonInformationEntry {
10     use gimli::write::CallFrameInstruction;
11 
12     let mut entry = CommonInformationEntry::new(
13         Encoding {
14             address_size: 8,
15             format: Format::Dwarf32,
16             version: 1,
17         },
18         4,  // Code alignment factor
19         -8, // Data alignment factor
20         Register(regs::link_reg().get_hw_encoding().into()),
21     );
22 
23     // Every frame will start with the call frame address (CFA) at SP
24     let sp = Register(regs::stack_reg().get_hw_encoding().into());
25     entry.add_instruction(CallFrameInstruction::Cfa(sp, 0));
26 
27     entry
28 }
29 
30 /// Map Cranelift registers to their corresponding Gimli registers.
map_reg(reg: Reg) -> Result<Register, RegisterMappingError>31 pub fn map_reg(reg: Reg) -> Result<Register, RegisterMappingError> {
32     // For AArch64 DWARF register mappings, see:
33     //
34     // https://developer.arm.com/documentation/ihi0057/e/?lang=en#dwarf-register-names
35     //
36     // X0--X31 is 0--31; V0--V31 is 64--95.
37     match reg.get_class() {
38         RegClass::I64 => {
39             let reg = reg.get_hw_encoding() as u16;
40             Ok(Register(reg))
41         }
42         RegClass::V128 => {
43             let reg = reg.get_hw_encoding() as u16;
44             Ok(Register(64 + reg))
45         }
46         _ => Err(RegisterMappingError::UnsupportedRegisterBank("class?")),
47     }
48 }
49 
50 pub(crate) struct RegisterMapper;
51 
52 impl crate::isa::unwind::systemv::RegisterMapper<Reg> for RegisterMapper {
map(&self, reg: Reg) -> Result<u16, RegisterMappingError>53     fn map(&self, reg: Reg) -> Result<u16, RegisterMappingError> {
54         Ok(map_reg(reg)?.0)
55     }
sp(&self) -> u1656     fn sp(&self) -> u16 {
57         regs::stack_reg().get_hw_encoding().into()
58     }
fp(&self) -> Option<u16>59     fn fp(&self) -> Option<u16> {
60         Some(regs::fp_reg().get_hw_encoding().into())
61     }
lr(&self) -> Option<u16>62     fn lr(&self) -> Option<u16> {
63         Some(regs::link_reg().get_hw_encoding().into())
64     }
lr_offset(&self) -> Option<u32>65     fn lr_offset(&self) -> Option<u32> {
66         Some(8)
67     }
68 }
69