ruby-changes:73125
From: Kevin <ko1@a...>
Date: Tue, 30 Aug 2022 00:53:42 +0900 (JST)
Subject: [ruby-changes:73125] b63f8bb456 (master): LDUR (https://github.com/Shopify/ruby/pull/295)
https://git.ruby-lang.org/ruby.git/commit/?id=b63f8bb456 From b63f8bb45619c891ce45466031012c0a48defefe Mon Sep 17 00:00:00 2001 From: Kevin Newton <kddnewton@g...> Date: Tue, 7 Jun 2022 14:20:43 -0400 Subject: LDUR (https://github.com/Shopify/ruby/pull/295) * LDUR * Fix up immediate masking * Consume operands directly * Consistency and cleanup * More consistency and entrypoints * Cleaner syntax for masks * Cleaner shifting for encodings --- yjit/src/asm/arm64/inst/branches_and_system.rs | 28 ++-- .../asm/arm64/inst/data_processing_immediate.rs | 143 ++++++++----------- .../src/asm/arm64/inst/data_processing_register.rs | 154 +++++++++------------ yjit/src/asm/arm64/inst/loads_and_stores.rs | 99 +++++++++++++ yjit/src/asm/arm64/inst/mod.rs | 121 ++++++++++++++-- yjit/src/asm/arm64/opnd.rs | 40 +++++- 6 files changed, 379 insertions(+), 206 deletions(-) create mode 100644 yjit/src/asm/arm64/inst/loads_and_stores.rs diff --git a/yjit/src/asm/arm64/inst/branches_and_system.rs b/yjit/src/asm/arm64/inst/branches_and_system.rs index 6eece11b88..77e99c112a 100644 --- a/yjit/src/asm/arm64/inst/branches_and_system.rs +++ b/yjit/src/asm/arm64/inst/branches_and_system.rs @@ -1,8 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branches_and_system.rs#L1 -use super::{ - super::opnd::*, - family::Family, - sf::Sf -}; +use super::family::Family; /// The struct that represents an A64 branches and system instruction that can /// be encoded. @@ -14,7 +10,7 @@ use super::{ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branches_and_system.rs#L10 /// | rn.............. rm.............. | /// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+ /// -struct BranchesAndSystem { +pub struct BranchesAndSystem { /// The register holding the address to be branched to. rn: u8 } @@ -22,28 +18,24 @@ struct BranchesAndSystem { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branches_and_system.rs#L18 impl BranchesAndSystem { /// RET /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/RET--Return-from-subroutine-?lang=en - pub fn ret(rn: &A64Opnd) -> Self { - match rn { - A64Opnd::None => BranchesAndSystem { rn: 30 }, - A64Opnd::Reg(reg) => BranchesAndSystem { rn: reg.reg_no }, - _ => panic!("Invalid operand for RET") - } + pub fn ret(rn: u8) -> Self { + Self { rn } } } impl From<BranchesAndSystem> for u32 { - /// Convert a data processing instruction into a 32-bit value. + /// Convert an instruction into a 32-bit value. fn from(inst: BranchesAndSystem) -> Self { 0 | (0b11 << 30) - | (Family::BranchesAndSystem as u32).wrapping_shl(25) + | ((Family::BranchesAndSystem as u32) << 25) | (0b1001011111 << 16) - | (inst.rn as u32).wrapping_shl(5) + | ((inst.rn as u32) << 5) } } impl From<BranchesAndSystem> for [u8; 4] { - /// Convert a data processing instruction into a 4 byte array. + /// Convert an instruction into a 4 byte array. fn from(inst: BranchesAndSystem) -> [u8; 4] { let result: u32 = inst.into(); result.to_le_bytes() @@ -56,14 +48,14 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/branches_and_system.rs#L48 #[test] fn test_ret() { - let inst = BranchesAndSystem::ret(&A64Opnd::None); + let inst = BranchesAndSystem::ret(30); let result: u32 = inst.into(); assert_eq!(0xd65f03C0, result); } #[test] fn test_ret_rn() { - let inst = BranchesAndSystem::ret(&X20); + let inst = BranchesAndSystem::ret(20); let result: u32 = inst.into(); assert_eq!(0xd65f0280, result); } diff --git a/yjit/src/asm/arm64/inst/data_processing_immediate.rs b/yjit/src/asm/arm64/inst/data_processing_immediate.rs index 12498848b2..25117efc22 100644 --- a/yjit/src/asm/arm64/inst/data_processing_immediate.rs +++ b/yjit/src/asm/arm64/inst/data_processing_immediate.rs @@ -1,8 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/data_processing_immediate.rs#L1 -use super::{ - super::opnd::*, - family::Family, - sf::Sf -}; +use super::{family::Family, sf::Sf}; /// The operation being performed by this instruction. enum Op { @@ -33,127 +29,106 @@ enum Shift { https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/arm64/inst/data_processing_immediate.rs#L29 /// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+ /// pub struct DataProcessingImmediate { - /// Whether or not this instruction is operating on 64-bit operands. - sf: Sf, + /// The register number of the destination register. + rd: u8, - /// The opcode for this instruction. - op: Op, + /// The register number of the first operand register. + rn: u8, - /// Whether or not to update the flags when this instruction is performed. - s: S, + /// The value of the immediate. + imm12: u16, /// How much to shift the immediate by. shift: Shift, - /// The value of the immediate. - imm12: u16, + /// Whether or not to update the flags when this instruction is performed. + s: S, - /// The register number of the first operand register. - rn: u8, + /// The opcode for this instruction. + op: Op, - /// The register number of the destination register. - rd: u8 + /// Whether or not this instruction is operating on 64-bit operands. + sf: Sf } impl DataProcessingImmediate { /// ADD (immediate) /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADD--immediate---Add--immediate--?lang=en - pub fn add(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self { - let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12); - + pub fn add(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self { Self { - sf: rd.num_bits.into(), - op: Op::Add, - s: S::LeaveFlags, + rd, + rn, + imm12, shift: Shift::LSL0, - imm12: imm12.value as u16, - rn: rn.reg_no, - rd: rd.reg_no + s: S::LeaveFlags, + op: Op::Add, + sf: num_bits.into() } } /// ADDS (immediate, set flags) /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADDS--immediate---Add--immediate---setting-flags-?lang=en - pub fn adds(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self { - let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12); - + pub fn adds(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self { Self { - sf: rd.num_bits.into(), - op: Op::Add, - s: S::UpdateFlags, + rd, + rn, + imm12, shift: Shift::LSL0, - imm12: imm12.value as u16, - rn: rn.reg_no, - rd: rd.reg_no + s: S::UpdateFlags, + op: Op::Add, + sf: num_bits.into() } } /// SUB (immediate) /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/SUB--immediate---Subtract--immediate--?lang=en - pub fn sub(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self { - let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12); - + pub fn sub(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self { Self { - sf: rd.num_bits.into(), - op: Op::Sub, - s: S::LeaveFlags, + rd, + rn, + imm12, shift: Shift::LSL0, - imm12: imm12.value as u16, - rn: rn.reg_no, - rd: rd.reg_no + s: S::LeaveFlags, + op: Op::Sub, + sf: num_bits.into() } } /// SUBS (immediate, set flags) /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/SUBS--immediate---Subtract--immediate---setting-flags-?lang=en - pub fn subs(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self { - let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12); - + pub fn subs(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self { Self { - sf: rd.num_bits.into(), - op: Op::Sub, - s: S::UpdateFlags, + rd, + rn, + imm12, shift: Shift::LSL0, - imm12: imm12.value as u16, - rn: rn.reg_no, - rd: rd.reg_no - } - } - - /// Extract out two registers and an immediate from the given operands. - /// Panic if any of the operands do not match the expected type or size. - fn unwrap<'a>(rd: &'a A64Opnd, rn: &'a A64Opnd, imm12: &'a A64Opnd) -> (&'a A64Reg, &'a A64Reg, &'a A64UImm) { - match (rd, rn, imm12) { - (A64Opnd::Reg(rd), A64Opnd::Reg(rn), A64Opnd::UImm(imm12)) => { - assert!(rd.num_bits == rn.num_bits, "Both rd and rn operands to a data processing immediate instruction must be of the same size."); - assert!(imm12.num_bits <= 12, "The immediate operand to a data processing immediate instruction must be 12 bits or less."); - (rd, rn, imm12) - }, - _ => { - panic!("Expected 2 register operands and an immediate operand for a data processing immediate instruction."); - } + s: S::UpdateFlags, + op: Op::Sub, + sf: num_bits.into() } } } impl From<DataProcessingImmediate> for u32 { - /// Convert a data processing instruction into a 32-bit value. + /// Convert an instruction into a 32-bit value. fn from(inst: DataProcess (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/