diff options
author | Kevin Newton <kddnewton@gmail.com> | 2022-08-26 19:21:45 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-29 09:09:41 -0700 |
commit | d694f320e40e77ab432f4d21575251ac0ab4ab76 (patch) | |
tree | a7cae862ea2bd33a3bc71e77d4b966772b71af5b /yjit/src/asm/arm64/inst/call.rs | |
parent | 46007b88af82d6ff22fc01edb7c74922dfa5c68a (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.rs | 14 |
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); } } |