summaryrefslogtreecommitdiff
path: root/yjit/src/asm/arm64/arg/inst_offset.rs
blob: f4a6bc73a067115666c99cf4dcee332bea39e523 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/// There are a lot of instructions in the AArch64 architectrue that take an
/// offset in terms of number of instructions. Usually they are jump
/// instructions or instructions that load a value relative to the current PC.
///
/// This struct is used to mark those locations instead of a generic operand in
/// order to give better clarity to the developer when reading the AArch64
/// backend code. It also helps to clarify that everything is in terms of a
/// number of instructions and not a number of bytes (i.e., the offset is the
/// number of bytes divided by 4).
#[derive(Copy, Clone)]
pub struct InstructionOffset(i32);

impl InstructionOffset {
    /// Create a new instruction offset.
    pub fn from_insns(insns: i32) -> Self {
        InstructionOffset(insns)
    }

    /// Create a new instruction offset from a number of bytes.
    pub fn from_bytes(bytes: i32) -> Self {
        assert_eq!(bytes % 4, 0, "Byte offset must be a multiple of 4");
        InstructionOffset(bytes / 4)
    }
}

impl From<i32> for InstructionOffset {
    /// Convert an i64 into an instruction offset.
    fn from(value: i32) -> Self {
        InstructionOffset(value)
    }
}

impl From<InstructionOffset> for i32 {
    /// Convert an instruction offset into a number of instructions as an i32.
    fn from(offset: InstructionOffset) -> Self {
        offset.0
    }
}

impl From<InstructionOffset> for i64 {
    /// Convert an instruction offset into a number of instructions as an i64.
    /// This is useful for when we're checking how many bits this offset fits
    /// into.
    fn from(offset: InstructionOffset) -> Self {
        offset.0.into()
    }
}