summaryrefslogtreecommitdiff
path: root/yjit/src/asm/arm64/inst/call.rs
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2022-09-09 11:37:41 -0400
committerGitHub <noreply@github.com>2022-09-09 11:37:41 -0400
commit848037cadd63091d5c39d06cd5d49aeee2258b4e (patch)
treeafd060fa7289b5d0851382e03e76f47a9d22cef6 /yjit/src/asm/arm64/inst/call.rs
parentb350053ae47dc4653ecb85f64360cf6eafba6323 (diff)
Better offsets (#6315)
* Introduce InstructionOffset for AArch64 There are a lot of instructions on AArch64 where we take an offset from PC in terms of the number of instructions. This is for loading a value relative to the PC or for jumping. We were usually accepting an A64Opnd or an i32. It can get confusing and inconsistent though because sometimes you would divide by 4 to get the number of instructions or multiply by 4 to get the number of bytes. This commit adds a struct that wraps an i32 in order to keep all of that logic in one place. It makes it much easier to read and reason about how these offsets are getting used. * Use b instruction when the offset fits on AArch64
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'yjit/src/asm/arm64/inst/call.rs')
-rw-r--r--yjit/src/asm/arm64/inst/call.rs28
1 files changed, 14 insertions, 14 deletions
diff --git a/yjit/src/asm/arm64/inst/call.rs b/yjit/src/asm/arm64/inst/call.rs
index 32d924f799..74debac7f7 100644
--- a/yjit/src/asm/arm64/inst/call.rs
+++ b/yjit/src/asm/arm64/inst/call.rs
@@ -1,4 +1,4 @@
-use super::super::arg::truncate_imm;
+use super::super::arg::{InstructionOffset, truncate_imm};
/// The operation to perform for this instruction.
enum Op {
@@ -20,8 +20,8 @@ enum Op {
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
///
pub struct Call {
- /// The PC-relative offset to jump to (which will be multiplied by 4).
- imm26: i32,
+ /// The PC-relative offset to jump to in terms of number of instructions.
+ offset: InstructionOffset,
/// The operation to perform for this instruction.
op: Op
@@ -30,14 +30,14 @@ pub struct Call {
impl Call {
/// B
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/B--Branch-
- pub fn b(imm26: i32) -> Self {
- Self { imm26, op: Op::Branch }
+ pub fn b(offset: InstructionOffset) -> Self {
+ Self { offset, op: Op::Branch }
}
/// BL
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/BL--Branch-with-Link-?lang=en
- pub fn bl(imm26: i32) -> Self {
- Self { imm26, op: Op::BranchWithLink }
+ pub fn bl(offset: InstructionOffset) -> Self {
+ Self { offset, op: Op::BranchWithLink }
}
}
@@ -50,7 +50,7 @@ impl From<Call> for u32 {
0
| ((inst.op as u32) << 31)
| (FAMILY << 26)
- | truncate_imm::<_, 26>(inst.imm26)
+ | truncate_imm::<_, 26>(inst.offset)
}
}
@@ -68,37 +68,37 @@ mod tests {
#[test]
fn test_bl() {
- let result: u32 = Call::bl(0).into();
+ let result: u32 = Call::bl(0.into()).into();
assert_eq!(0x94000000, result);
}
#[test]
fn test_bl_positive() {
- let result: u32 = Call::bl(256).into();
+ let result: u32 = Call::bl(256.into()).into();
assert_eq!(0x94000100, result);
}
#[test]
fn test_bl_negative() {
- let result: u32 = Call::bl(-256).into();
+ let result: u32 = Call::bl((-256).into()).into();
assert_eq!(0x97ffff00, result);
}
#[test]
fn test_b() {
- let result: u32 = Call::b(0).into();
+ let result: u32 = Call::b(0.into()).into();
assert_eq!(0x14000000, result);
}
#[test]
fn test_b_positive() {
- let result: u32 = Call::b((1 << 25) - 1).into();
+ let result: u32 = Call::b(((1 << 25) - 1).into()).into();
assert_eq!(0x15ffffff, result);
}
#[test]
fn test_b_negative() {
- let result: u32 = Call::b(-(1 << 25)).into();
+ let result: u32 = Call::b((-(1 << 25)).into()).into();
assert_eq!(0x16000000, result);
}
}