summaryrefslogtreecommitdiff
path: root/yjit/src/asm/arm64/inst/call.rs
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2022-08-26 19:21:45 -0400
committerTakashi Kokubun <takashikkbn@gmail.com>2022-08-29 09:09:41 -0700
commitd694f320e40e77ab432f4d21575251ac0ab4ab76 (patch)
treea7cae862ea2bd33a3bc71e77d4b966772b71af5b /yjit/src/asm/arm64/inst/call.rs
parent46007b88af82d6ff22fc01edb7c74922dfa5c68a (diff)
Fixed width immediates (https://github.com/Shopify/ruby/pull/437)
There are a lot of times when encoding AArch64 instructions that we need to represent an integer value with a custom fixed width. For example, the offset for a B instruction is 26 bits, so we store an i32 on the instruction struct and then mask it when we encode. We've been doing this masking everywhere, which has worked, but it's getting a bit copy-pasty all over the place. This commit centralizes that logic to make sure we stay consistent.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6289
Diffstat (limited to 'yjit/src/asm/arm64/inst/call.rs')
-rw-r--r--yjit/src/asm/arm64/inst/call.rs14
1 files changed, 7 insertions, 7 deletions
diff --git a/yjit/src/asm/arm64/inst/call.rs b/yjit/src/asm/arm64/inst/call.rs
index 8d65359f77..32d924f799 100644
--- a/yjit/src/asm/arm64/inst/call.rs
+++ b/yjit/src/asm/arm64/inst/call.rs
@@ -1,3 +1,5 @@
+use super::super::arg::truncate_imm;
+
/// The operation to perform for this instruction.
enum Op {
/// Branch directly, with a hint that this is not a subroutine call or
@@ -45,12 +47,10 @@ const FAMILY: u32 = 0b101;
impl From<Call> for u32 {
/// Convert an instruction into a 32-bit value.
fn from(inst: Call) -> Self {
- let imm26 = (inst.imm26 as u32) & ((1 << 26) - 1);
-
0
| ((inst.op as u32) << 31)
| (FAMILY << 26)
- | imm26
+ | truncate_imm::<_, 26>(inst.imm26)
}
}
@@ -92,13 +92,13 @@ mod tests {
#[test]
fn test_b_positive() {
- let result: u32 = Call::b(256).into();
- assert_eq!(0x14000100, result);
+ let result: u32 = Call::b((1 << 25) - 1).into();
+ assert_eq!(0x15ffffff, result);
}
#[test]
fn test_b_negative() {
- let result: u32 = Call::b(-256).into();
- assert_eq!(0x17ffff00, result);
+ let result: u32 = Call::b(-(1 << 25)).into();
+ assert_eq!(0x16000000, result);
}
}