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/