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

ruby-changes:73168

From: Kevin <ko1@a...>
Date: Tue, 30 Aug 2022 00:57:49 +0900 (JST)
Subject: [ruby-changes:73168] 7a9b581e08 (master): Arm64 progress (https://github.com/Shopify/ruby/pull/304)

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

From 7a9b581e0896d4aa7a037da90c837b830213c8e8 Mon Sep 17 00:00:00 2001
From: Kevin Newton <kddnewton@g...>
Date: Tue, 5 Jul 2022 16:04:19 -0400
Subject: Arm64 progress (https://github.com/Shopify/ruby/pull/304)

* Get initial wiring up

* Split IncrCounter instruction

* Breakpoints in Arm64

* Support for ORR

* MOV instruction encodings

* Implement JmpOpnd and CRet

* Add ORN

* Add MVN

* PUSH, POP, CCALL for Arm64

* Some formatting and implement Op::Not for Arm64

* Consistent constants when working with the Arm64 SP

* Allow OR-ing values into the memory buffer

* Test lowering Arm64 ADD

* Emit unconditional jumps consistently in Arm64

* Begin emitting conditional jumps for A64

* Back out some labelref changes

* Remove label API that no longer exists

* Use a trait for the label encoders

* Encode nop

* Add in nops so jumps are the same width no matter what on Arm64

* Op::Jbe for CodePtr

* Pass src_addr and dst_addr instead of calculated offset to label refs

* Even more jump work for Arm64

* Fix up jumps to use consistent assertions

* Handle splitting Add, Sub, and Not insns for Arm64

* More Arm64 splits and various fixes

* PR feedback for Arm64 support

* Split up jumps and conditional jump logic
---
 yjit/src/asm/arm64/inst/breakpoint.rs  |  55 +++++
 yjit/src/asm/arm64/inst/call.rs        |  51 +++-
 yjit/src/asm/arm64/inst/logical_imm.rs |  37 ++-
 yjit/src/asm/arm64/inst/logical_reg.rs |  80 ++++++-
 yjit/src/asm/arm64/inst/mod.rs         |   4 +
 yjit/src/asm/arm64/inst/nop.rs         |  44 ++++
 yjit/src/asm/arm64/mod.rs              | 198 +++++++++++++++-
 yjit/src/asm/arm64/opnd.rs             |  48 ++--
 yjit/src/asm/mod.rs                    |  33 +--
 yjit/src/asm/x86_64/mod.rs             | 101 ++++----
 yjit/src/backend/arm64/mod.rs          | 410 ++++++++++++++++++++++++++++++---
 yjit/src/backend/ir.rs                 |   7 +
 yjit/src/backend/mod.rs                |   7 +-
 yjit/src/backend/x86_64/mod.rs         |   3 +
 14 files changed, 939 insertions(+), 139 deletions(-)
 create mode 100644 yjit/src/asm/arm64/inst/breakpoint.rs
 create mode 100644 yjit/src/asm/arm64/inst/nop.rs

diff --git a/yjit/src/asm/arm64/inst/breakpoint.rs b/yjit/src/asm/arm64/inst/breakpoint.rs
new file mode 100644
index 0000000000..be4920ac76
--- /dev/null
+++ b/yjit/src/asm/arm64/inst/breakpoint.rs
@@ -0,0 +1,55 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/breakpoint.rs#L1
+/// The struct that represents an A64 breakpoint instruction that can be encoded.
+///
+/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
+/// | 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | 19 18 17 16 | 15 14 13 12 | 11 10 09 08 | 07 06 05 04 | 03 02 01 00 |
+/// |  1  1  0  1    0  1  0  0    0  0  1                                                          0    0  0  0  0 |
+/// |                                      imm16..................................................                  |
+/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
+///
+pub struct Breakpoint {
+    /// The value to be captured by ESR_ELx.ISS
+    imm16: u16
+}
+
+impl Breakpoint {
+    /// BRK
+    /// https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BRK--Breakpoint-instruction-
+    pub fn brk(imm16: u16) -> Self {
+        Self { imm16 }
+    }
+}
+
+/// https://developer.arm.com/documentation/ddi0602/2022-03/Index-by-Encoding/Branches--Exception-Generating-and-System-instructions?lang=en#control
+const FAMILY: u32 = 0b101;
+
+impl From<Breakpoint> for u32 {
+    /// Convert an instruction into a 32-bit value.
+    fn from(inst: Breakpoint) -> Self {
+        let imm16 = inst.imm16 as u32;
+
+        0
+        | (0b11 << 30)
+        | (FAMILY << 26)
+        | (1 << 21)
+        | (imm16 << 5)
+    }
+}
+
+impl From<Breakpoint> for [u8; 4] {
+    /// Convert an instruction into a 4 byte array.
+    fn from(inst: Breakpoint) -> [u8; 4] {
+        let result: u32 = inst.into();
+        result.to_le_bytes()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_brk() {
+        let result: u32 = Breakpoint::brk(7).into();
+        assert_eq!(0xd42000e0, result);
+    }
+}
diff --git a/yjit/src/asm/arm64/inst/call.rs b/yjit/src/asm/arm64/inst/call.rs
index 6f23acf9f5..8d65359f77 100644
--- a/yjit/src/asm/arm64/inst/call.rs
+++ b/yjit/src/asm/arm64/inst/call.rs
@@ -1,22 +1,41 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/call.rs#L1
-/// The struct that represents an A64 branch with link instruction that can be
-/// encoded.
+/// The operation to perform for this instruction.
+enum Op {
+    /// Branch directly, with a hint that this is not a subroutine call or
+    /// return.
+    Branch = 0,
+
+    /// Branch directly, with a hint that this is a subroutine call or return.
+    BranchWithLink = 1
+}
+
+/// The struct that represents an A64 branch with our without link instruction
+/// that can be encoded.
 ///
 /// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
 /// | 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | 19 18 17 16 | 15 14 13 12 | 11 10 09 08 | 07 06 05 04 | 03 02 01 00 |
-/// |  1  0  0  1    0  1                                                                                           |
-/// |                     imm26.................................................................................... |
+/// |     0  0  1    0  1                                                                                           |
+/// | op                  imm26.................................................................................... |
 /// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
 ///
 pub struct Call {
     /// The PC-relative offset to jump to (which will be multiplied by 4).
-    imm26: i32
+    imm26: i32,
+
+    /// The operation to perform for this instruction.
+    op: Op
 }
 
 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 }
+    }
+
     /// 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 }
+        Self { imm26, op: Op::BranchWithLink }
     }
 }
 
@@ -29,7 +48,7 @@ impl From<Call> for u32 { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/call.rs#L48
         let imm26 = (inst.imm26 as u32) & ((1 << 26) - 1);
 
         0
-        | (1 << 31)
+        | ((inst.op as u32) << 31)
         | (FAMILY << 26)
         | imm26
     }
@@ -64,4 +83,22 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/call.rs#L83
         let result: u32 = Call::bl(-256).into();
         assert_eq!(0x97ffff00, result);
     }
+
+    #[test]
+    fn test_b() {
+        let result: u32 = Call::b(0).into();
+        assert_eq!(0x14000000, result);
+    }
+
+    #[test]
+    fn test_b_positive() {
+        let result: u32 = Call::b(256).into();
+        assert_eq!(0x14000100, result);
+    }
+
+    #[test]
+    fn test_b_negative() {
+        let result: u32 = Call::b(-256).into();
+        assert_eq!(0x17ffff00, result);
+    }
 }
diff --git a/yjit/src/asm/arm64/inst/logical_imm.rs b/yjit/src/asm/arm64/inst/logical_imm.rs
index cc2a16cbdc..13865697f6 100644
--- a/yjit/src/asm/arm64/inst/logical_imm.rs
+++ b/yjit/src/asm/arm64/inst/logical_imm.rs
@@ -5,6 +5,9 @@ enum Opc { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/logical_imm.rs#L5
     /// The AND operation.
     And = 0b00,
 
+    /// The ORR operation.
+    Orr = 0b01,
+
     /// The ANDS operation.
     Ands = 0b11
 }
@@ -12,7 +15,7 @@ enum Opc { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/logical_imm.rs#L15
 /// The struct that represents an A64 bitwise immediate instruction that can be
 /// encoded.
 ///
-/// AND/ANDS (immediate)
+/// AND/ORR/ANDS (immediate)
 /// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
 /// | 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | 19 18 17 16 | 15 14 13 12 | 11 10 09 08 | 07 06 05 04 | 03 02 01 00 |
 /// |           1    0  0  1  0    0                                                                                |
@@ -37,19 +40,31 @@ pub struct LogicalImm { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/logical_imm.rs#L40
 }
 
 impl LogicalImm {
-    /// AND (immediate)
+    /// AND (bitmask immediate)
     /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/AND--immediate---Bitwise-AND--immediate--?lang=en
     pub fn and(rd: u8, rn: u8, imm: BitmaskImmediate, num_bits: u8) -> Self {
         Self { rd, rn, imm, opc: Opc::And, sf: num_bits.into() }
     }
 
-    /// ANDS (immediate)
+    /// ANDS (bitmask immediate)
     /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ANDS--immediate---Bitwise-AND--immediate---setting-flags-?lang=en
     pub fn ands(rd: u8, rn: u8, imm: BitmaskImmediate, num_bits: u8) -> Self {
         Self { rd, rn, imm, opc: Opc::Ands, sf: num_bits.into() }
     }
 
-    /// TST (immediate)
+    /// MOV (bitmask immediate)
+    /// https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/MOV--bitmask-immediate---Move--bitmask-immediate---an-alias-of-ORR--immediate--?lang=en
+    pub fn mov(rd: u8, imm: BitmaskImmediate, num_bits: u8) -> Self {
+        Self { rd, rn: 0b11111, imm, opc: Opc::Orr, sf: num_bits.into() }
+    }
+
+    /// ORR (bitmask immediate)
+    /// https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/ORR--immediate---Bitwise-OR--immediat (... truncated)

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

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