Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions yjit/src/asm/arm64/inst/branch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/// Which operation to perform.
enum Op {
/// Perform a BR instruction.
Br = 0b00,

/// Perform a RET instruction.
Ret = 0b10
}

/// The struct that represents an A64 branch 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 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 |
/// | op... rn.............. rm.............. |
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
///
pub struct Branch {
/// The register holding the address to be branched to.
rn: u8,

/// The operation to perform.
op: Op
}

impl Branch {
/// 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 }
}

/// 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 }
}
}

/// https://developer.arm.com/documentation/ddi0602/2022-03/Index-by-Encoding/Branches--Exception-Generating-and-System-instructions?lang=en
const FAMILY: u32 = 0b101;

impl From<Branch> for u32 {
/// Convert an instruction into a 32-bit value.
fn from(inst: Branch) -> Self {
0
| (0b11 << 30)
| (FAMILY << 26)
| (1 << 25)
| ((inst.op as u32) << 21)
| (0b11111 << 16)
| ((inst.rn as u32) << 5)
}
}

impl From<Branch> for [u8; 4] {
/// Convert an instruction into a 4 byte array.
fn from(inst: Branch) -> [u8; 4] {
let result: u32 = inst.into();
result.to_le_bytes()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_br() {
let result: u32 = Branch::br(0).into();
assert_eq!(0xd61f0000, result);
}

#[test]
fn test_ret() {
let result: u32 = Branch::ret(30).into();
assert_eq!(0xd65f03C0, result);
}

#[test]
fn test_ret_rn() {
let result: u32 = Branch::ret(20).into();
assert_eq!(0xd65f0280, result);
}
}
62 changes: 0 additions & 62 deletions yjit/src/asm/arm64/inst/branches_and_system.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{family::Family, sf::Sf};
use super::sf::Sf;

/// The operation being performed by this instruction.
enum Op {
Expand Down Expand Up @@ -28,7 +28,7 @@ enum Shift {
/// | sf op S sh imm12.................................... rn.............. rd.............. |
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
///
pub struct DataProcessingImmediate {
pub struct DataImm {
/// The register number of the destination register.
rd: u8,

Expand All @@ -51,7 +51,7 @@ pub struct DataProcessingImmediate {
sf: Sf
}

impl DataProcessingImmediate {
impl DataImm {
/// ADD (immediate)
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADD--immediate---Add--immediate--?lang=en
pub fn add(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self {
Expand Down Expand Up @@ -109,16 +109,19 @@ impl DataProcessingImmediate {
}
}

impl From<DataProcessingImmediate> for u32 {
/// https://developer.arm.com/documentation/ddi0602/2022-03/Index-by-Encoding/Data-Processing----Immediate?lang=en
const FAMILY: u32 = 0b1000;

impl From<DataImm> for u32 {
/// Convert an instruction into a 32-bit value.
fn from(inst: DataProcessingImmediate) -> Self {
fn from(inst: DataImm) -> Self {
let imm12 = (inst.imm12 as u32) & ((1 << 12) - 1);

0
| ((inst.sf as u32) << 31)
| ((inst.op as u32) << 30)
| ((inst.s as u32) << 29)
| ((Family::DataProcessingImmediate as u32) << 25)
| (FAMILY << 25)
| (1 << 24)
| ((inst.shift as u32) << 22)
| (imm12 << 10)
Expand All @@ -127,9 +130,9 @@ impl From<DataProcessingImmediate> for u32 {
}
}

impl From<DataProcessingImmediate> for [u8; 4] {
impl From<DataImm> for [u8; 4] {
/// Convert an instruction into a 4 byte array.
fn from(inst: DataProcessingImmediate) -> [u8; 4] {
fn from(inst: DataImm) -> [u8; 4] {
let result: u32 = inst.into();
result.to_le_bytes()
}
Expand All @@ -141,28 +144,28 @@ mod tests {

#[test]
fn test_add() {
let inst = DataProcessingImmediate::add(0, 1, 7, 64);
let inst = DataImm::add(0, 1, 7, 64);
let result: u32 = inst.into();
assert_eq!(0x91001c20, result);
}

#[test]
fn test_adds() {
let inst = DataProcessingImmediate::adds(0, 1, 7, 64);
let inst = DataImm::adds(0, 1, 7, 64);
let result: u32 = inst.into();
assert_eq!(0xb1001c20, result);
}

#[test]
fn test_sub() {
let inst = DataProcessingImmediate::sub(0, 1, 7, 64);
let inst = DataImm::sub(0, 1, 7, 64);
let result: u32 = inst.into();
assert_eq!(0xd1001c20, result);
}

#[test]
fn test_subs() {
let inst = DataProcessingImmediate::subs(0, 1, 7, 64);
let inst = DataImm::subs(0, 1, 7, 64);
let result: u32 = inst.into();
assert_eq!(0xf1001c20, result);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{family::Family, sf::Sf};
use super::sf::Sf;

/// The operation being performed by this instruction.
enum Op {
Expand Down Expand Up @@ -29,7 +29,7 @@ enum Shift {
/// | sf op S shift rm.............. imm6............... rn.............. rd.............. |
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
///
pub struct DataProcessingRegister {
pub struct DataReg {
/// The register number of the destination register.
rd: u8,

Expand All @@ -55,7 +55,7 @@ pub struct DataProcessingRegister {
sf: Sf
}

impl DataProcessingRegister {
impl DataReg {
/// ADD (shifted register)
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADD--shifted-register---Add--shifted-register--?lang=en
pub fn add(rd: u8, rn: u8, rm: u8, num_bits: u8) -> Self {
Expand Down Expand Up @@ -117,16 +117,19 @@ impl DataProcessingRegister {
}
}

impl From<DataProcessingRegister> for u32 {
/// https://developer.arm.com/documentation/ddi0602/2022-03/Index-by-Encoding/Data-Processing----Register?lang=en
const FAMILY: u32 = 0b0101;

impl From<DataReg> for u32 {
/// Convert an instruction into a 32-bit value.
fn from(inst: DataProcessingRegister) -> Self {
fn from(inst: DataReg) -> Self {
let imm6 = (inst.imm6 as u32) & ((1 << 6) - 1);

0
| ((inst.sf as u32) << 31)
| ((inst.op as u32) << 30)
| ((inst.s as u32) << 29)
| ((Family::DataProcessingRegister as u32) << 25)
| (FAMILY << 25)
| (1 << 24)
| ((inst.shift as u32) << 22)
| ((inst.rm as u32) << 16)
Expand All @@ -136,9 +139,9 @@ impl From<DataProcessingRegister> for u32 {
}
}

impl From<DataProcessingRegister> for [u8; 4] {
impl From<DataReg> for [u8; 4] {
/// Convert an instruction into a 4 byte array.
fn from(inst: DataProcessingRegister) -> [u8; 4] {
fn from(inst: DataReg) -> [u8; 4] {
let result: u32 = inst.into();
result.to_le_bytes()
}
Expand All @@ -150,28 +153,28 @@ mod tests {

#[test]
fn test_add() {
let inst = DataProcessingRegister::add(0, 1, 2, 64);
let inst = DataReg::add(0, 1, 2, 64);
let result: u32 = inst.into();
assert_eq!(0x8b020020, result);
}

#[test]
fn test_adds() {
let inst = DataProcessingRegister::adds(0, 1, 2, 64);
let inst = DataReg::adds(0, 1, 2, 64);
let result: u32 = inst.into();
assert_eq!(0xab020020, result);
}

#[test]
fn test_sub() {
let inst = DataProcessingRegister::sub(0, 1, 2, 64);
let inst = DataReg::sub(0, 1, 2, 64);
let result: u32 = inst.into();
assert_eq!(0xcb020020, result);
}

#[test]
fn test_subs() {
let inst = DataProcessingRegister::subs(0, 1, 2, 64);
let inst = DataReg::subs(0, 1, 2, 64);
let result: u32 = inst.into();
assert_eq!(0xeb020020, result);
}
Expand Down
34 changes: 0 additions & 34 deletions yjit/src/asm/arm64/inst/family.rs

This file was deleted.

Loading