Skip to content

Commit

Permalink
MOVK, MOVZ, BR (#296)
Browse files Browse the repository at this point in the history
* MOVK instruction

* More tests for the A64 entrypoints

* Finish testing entrypoints

* MOVZ

* BR instruction
  • Loading branch information
kddnewton authored and k0kubun committed Aug 25, 2022
1 parent f752fd4 commit 0edbb26
Show file tree
Hide file tree
Showing 9 changed files with 442 additions and 158 deletions.
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.

0 comments on commit 0edbb26

Please sign in to comment.