[前][次][番号順一覧][スレッド一覧]

ruby-changes:73206

From: Kevin <ko1@a...>
Date: Tue, 30 Aug 2022 01:00:25 +0900 (JST)
Subject: [ruby-changes:73206] db84d2921f (master): BLR instruction for AArch64 (https://github.com/Shopify/ruby/pull/325)

https://git.ruby-lang.org/ruby.git/commit/?id=db84d2921f

From db84d2921fc2ae1397c75cbf5d6752dd10f94219 Mon Sep 17 00:00:00 2001
From: Kevin Newton <kddnewton@g...>
Date: Tue, 19 Jul 2022 12:10:23 -0400
Subject: BLR instruction for AArch64
 (https://github.com/Shopify/ruby/pull/325)

---
 yjit/src/asm/arm64/inst/branch.rs | 23 +++++++++++++++++++----
 yjit/src/asm/arm64/mod.rs         | 15 +++++++++++++++
 yjit/src/backend/arm64/mod.rs     |  7 +++----
 3 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/yjit/src/asm/arm64/inst/branch.rs b/yjit/src/asm/arm64/inst/branch.rs
index 7f93f5e201..f15ef2a9b0 100644
--- a/yjit/src/asm/arm64/inst/branch.rs
+++ b/yjit/src/asm/arm64/inst/branch.rs
@@ -1,10 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branch.rs#L1
 /// Which operation to perform.
 enum Op {
     /// Perform a BR instruction.
-    Br = 0b00,
+    BR = 0b00,
+
+    /// Perform a BLR instruction.
+    BLR = 0b01,
 
     /// Perform a RET instruction.
-    Ret = 0b10
+    RET = 0b10
 }
 
 /// The struct that represents an A64 branch instruction that can be encoded.
@@ -27,13 +30,19 @@ impl Branch { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branch.rs#L30
     /// BR
     /// https://developer.arm.com/documentation/ddi0602/2022-03/Base-Instructions/BR--Branch-to-Register-?lang=en
     pub fn br(rn: u8) -> Self {
-        Self { rn, op: Op::Br }
+        Self { rn, op: Op::BR }
+    }
+
+    /// BLR
+    /// https://developer.arm.com/documentation/ddi0602/2022-03/Base-Instructions/BLR--Branch-with-Link-to-Register-?lang=en
+    pub fn blr(rn: u8) -> Self {
+        Self { rn, op: Op::BLR }
     }
 
     /// RET
     /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/RET--Return-from-subroutine-?lang=en
     pub fn ret(rn: u8) -> Self {
-        Self { rn, op: Op::Ret }
+        Self { rn, op: Op::RET }
     }
 }
 
@@ -71,6 +80,12 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branch.rs#L80
         assert_eq!(0xd61f0000, result);
     }
 
+    #[test]
+    fn test_blr() {
+        let result: u32 = Branch::blr(0).into();
+        assert_eq!(0xd63f0000, result);
+    }
+
     #[test]
     fn test_ret() {
         let result: u32 = Branch::ret(30).into();
diff --git a/yjit/src/asm/arm64/mod.rs b/yjit/src/asm/arm64/mod.rs
index 333fce495f..8be7e6f568 100644
--- a/yjit/src/asm/arm64/mod.rs
+++ b/yjit/src/asm/arm64/mod.rs
@@ -226,6 +226,16 @@ pub fn bl(cb: &mut CodeBlock, imm26: A64Opnd) { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/mod.rs#L226
     cb.write_bytes(&bytes);
 }
 
+/// BLR - branch with link to a register
+pub fn blr(cb: &mut CodeBlock, rn: A64Opnd) {
+    let bytes: [u8; 4] = match rn {
+        A64Opnd::Reg(rn) => Branch::blr(rn.reg_no).into(),
+        _ => panic!("Invalid operand to blr instruction."),
+    };
+
+    cb.write_bytes(&bytes);
+}
+
 /// BR - branch to a register
 pub fn br(cb: &mut CodeBlock, rn: A64Opnd) {
     let bytes: [u8; 4] = match rn {
@@ -842,6 +852,11 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/mod.rs#L852
         check_bytes("00040094", |cb| bl(cb, A64Opnd::new_imm(1024)));
     }
 
+    #[test]
+    fn test_blr() {
+        check_bytes("80023fd6", |cb| blr(cb, X20));
+    }
+
     #[test]
     fn test_br() {
         check_bytes("80021fd6", |cb| br(cb, X20));
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs
index 69c35a3688..729ee06fa9 100644
--- a/yjit/src/backend/arm64/mod.rs
+++ b/yjit/src/backend/arm64/mod.rs
@@ -359,8 +359,8 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/arm64/mod.rs#L359
                             let value = dst_addr as u64;
 
                             b(cb, A64Opnd::new_imm(emit_load_size(value).into()));
-                            emit_load_value(cb, X29, value);
-                            br(cb, X29);
+                            emit_load_value(cb, Assembler::SCRATCH0, value);
+                            br(cb, Assembler::SCRATCH0);
                         }
                     }
                 },
@@ -572,8 +572,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/arm64/mod.rs#L572
                         bl(cb, A64Opnd::new_imm(offset / 4));
                     } else {
                         emit_load_value(cb, Self::SCRATCH0, dst_addr as u64);
-                        adr(cb, X30, A64Opnd::Imm(8));
-                        br(cb, Self::SCRATCH0);
+                        blr(cb, Self::SCRATCH0);
                     }
                 },
                 Op::CRet => {
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]