Skip to content

Commit d402cf2

Browse files
kddnewtonk0kubun
authored andcommitted
LDUR (#295)
* LDUR * Fix up immediate masking * Consume operands directly * Consistency and cleanup * More consistency and entrypoints * Cleaner syntax for masks * Cleaner shifting for encodings PR: #295
1 parent 331d90a commit d402cf2

File tree

6 files changed

+379
-206
lines changed

6 files changed

+379
-206
lines changed

yjit/src/asm/arm64/inst/branches_and_system.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use super::{
2-
super::opnd::*,
3-
family::Family,
4-
sf::Sf
5-
};
1+
use super::family::Family;
62

73
/// The struct that represents an A64 branches and system instruction that can
84
/// be encoded.
@@ -14,36 +10,32 @@ use super::{
1410
/// | rn.............. rm.............. |
1511
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
1612
///
17-
struct BranchesAndSystem {
13+
pub struct BranchesAndSystem {
1814
/// The register holding the address to be branched to.
1915
rn: u8
2016
}
2117

2218
impl BranchesAndSystem {
2319
/// RET
2420
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/RET--Return-from-subroutine-?lang=en
25-
pub fn ret(rn: &A64Opnd) -> Self {
26-
match rn {
27-
A64Opnd::None => BranchesAndSystem { rn: 30 },
28-
A64Opnd::Reg(reg) => BranchesAndSystem { rn: reg.reg_no },
29-
_ => panic!("Invalid operand for RET")
30-
}
21+
pub fn ret(rn: u8) -> Self {
22+
Self { rn }
3123
}
3224
}
3325

3426
impl From<BranchesAndSystem> for u32 {
35-
/// Convert a data processing instruction into a 32-bit value.
27+
/// Convert an instruction into a 32-bit value.
3628
fn from(inst: BranchesAndSystem) -> Self {
3729
0
3830
| (0b11 << 30)
39-
| (Family::BranchesAndSystem as u32).wrapping_shl(25)
31+
| ((Family::BranchesAndSystem as u32) << 25)
4032
| (0b1001011111 << 16)
41-
| (inst.rn as u32).wrapping_shl(5)
33+
| ((inst.rn as u32) << 5)
4234
}
4335
}
4436

4537
impl From<BranchesAndSystem> for [u8; 4] {
46-
/// Convert a data processing instruction into a 4 byte array.
38+
/// Convert an instruction into a 4 byte array.
4739
fn from(inst: BranchesAndSystem) -> [u8; 4] {
4840
let result: u32 = inst.into();
4941
result.to_le_bytes()
@@ -56,14 +48,14 @@ mod tests {
5648

5749
#[test]
5850
fn test_ret() {
59-
let inst = BranchesAndSystem::ret(&A64Opnd::None);
51+
let inst = BranchesAndSystem::ret(30);
6052
let result: u32 = inst.into();
6153
assert_eq!(0xd65f03C0, result);
6254
}
6355

6456
#[test]
6557
fn test_ret_rn() {
66-
let inst = BranchesAndSystem::ret(&X20);
58+
let inst = BranchesAndSystem::ret(20);
6759
let result: u32 = inst.into();
6860
assert_eq!(0xd65f0280, result);
6961
}

yjit/src/asm/arm64/inst/data_processing_immediate.rs

Lines changed: 57 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use super::{
2-
super::opnd::*,
3-
family::Family,
4-
sf::Sf
5-
};
1+
use super::{family::Family, sf::Sf};
62

73
/// The operation being performed by this instruction.
84
enum Op {
@@ -33,127 +29,106 @@ enum Shift {
3329
/// +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
3430
///
3531
pub struct DataProcessingImmediate {
36-
/// Whether or not this instruction is operating on 64-bit operands.
37-
sf: Sf,
32+
/// The register number of the destination register.
33+
rd: u8,
3834

39-
/// The opcode for this instruction.
40-
op: Op,
35+
/// The register number of the first operand register.
36+
rn: u8,
4137

42-
/// Whether or not to update the flags when this instruction is performed.
43-
s: S,
38+
/// The value of the immediate.
39+
imm12: u16,
4440

4541
/// How much to shift the immediate by.
4642
shift: Shift,
4743

48-
/// The value of the immediate.
49-
imm12: u16,
44+
/// Whether or not to update the flags when this instruction is performed.
45+
s: S,
5046

51-
/// The register number of the first operand register.
52-
rn: u8,
47+
/// The opcode for this instruction.
48+
op: Op,
5349

54-
/// The register number of the destination register.
55-
rd: u8
50+
/// Whether or not this instruction is operating on 64-bit operands.
51+
sf: Sf
5652
}
5753

5854
impl DataProcessingImmediate {
5955
/// ADD (immediate)
6056
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADD--immediate---Add--immediate--?lang=en
61-
pub fn add(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self {
62-
let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12);
63-
57+
pub fn add(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self {
6458
Self {
65-
sf: rd.num_bits.into(),
66-
op: Op::Add,
67-
s: S::LeaveFlags,
59+
rd,
60+
rn,
61+
imm12,
6862
shift: Shift::LSL0,
69-
imm12: imm12.value as u16,
70-
rn: rn.reg_no,
71-
rd: rd.reg_no
63+
s: S::LeaveFlags,
64+
op: Op::Add,
65+
sf: num_bits.into()
7266
}
7367
}
7468

7569
/// ADDS (immediate, set flags)
7670
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/ADDS--immediate---Add--immediate---setting-flags-?lang=en
77-
pub fn adds(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self {
78-
let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12);
79-
71+
pub fn adds(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self {
8072
Self {
81-
sf: rd.num_bits.into(),
82-
op: Op::Add,
83-
s: S::UpdateFlags,
73+
rd,
74+
rn,
75+
imm12,
8476
shift: Shift::LSL0,
85-
imm12: imm12.value as u16,
86-
rn: rn.reg_no,
87-
rd: rd.reg_no
77+
s: S::UpdateFlags,
78+
op: Op::Add,
79+
sf: num_bits.into()
8880
}
8981
}
9082

9183
/// SUB (immediate)
9284
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/SUB--immediate---Subtract--immediate--?lang=en
93-
pub fn sub(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self {
94-
let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12);
95-
85+
pub fn sub(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self {
9686
Self {
97-
sf: rd.num_bits.into(),
98-
op: Op::Sub,
99-
s: S::LeaveFlags,
87+
rd,
88+
rn,
89+
imm12,
10090
shift: Shift::LSL0,
101-
imm12: imm12.value as u16,
102-
rn: rn.reg_no,
103-
rd: rd.reg_no
91+
s: S::LeaveFlags,
92+
op: Op::Sub,
93+
sf: num_bits.into()
10494
}
10595
}
10696

10797
/// SUBS (immediate, set flags)
10898
/// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/SUBS--immediate---Subtract--immediate---setting-flags-?lang=en
109-
pub fn subs(rd: &A64Opnd, rn: &A64Opnd, imm12: &A64Opnd) -> Self {
110-
let (rd, rn, imm12) = Self::unwrap(rd, rn, imm12);
111-
99+
pub fn subs(rd: u8, rn: u8, imm12: u16, num_bits: u8) -> Self {
112100
Self {
113-
sf: rd.num_bits.into(),
114-
op: Op::Sub,
115-
s: S::UpdateFlags,
101+
rd,
102+
rn,
103+
imm12,
116104
shift: Shift::LSL0,
117-
imm12: imm12.value as u16,
118-
rn: rn.reg_no,
119-
rd: rd.reg_no
120-
}
121-
}
122-
123-
/// Extract out two registers and an immediate from the given operands.
124-
/// Panic if any of the operands do not match the expected type or size.
125-
fn unwrap<'a>(rd: &'a A64Opnd, rn: &'a A64Opnd, imm12: &'a A64Opnd) -> (&'a A64Reg, &'a A64Reg, &'a A64UImm) {
126-
match (rd, rn, imm12) {
127-
(A64Opnd::Reg(rd), A64Opnd::Reg(rn), A64Opnd::UImm(imm12)) => {
128-
assert!(rd.num_bits == rn.num_bits, "Both rd and rn operands to a data processing immediate instruction must be of the same size.");
129-
assert!(imm12.num_bits <= 12, "The immediate operand to a data processing immediate instruction must be 12 bits or less.");
130-
(rd, rn, imm12)
131-
},
132-
_ => {
133-
panic!("Expected 2 register operands and an immediate operand for a data processing immediate instruction.");
134-
}
105+
s: S::UpdateFlags,
106+
op: Op::Sub,
107+
sf: num_bits.into()
135108
}
136109
}
137110
}
138111

139112
impl From<DataProcessingImmediate> for u32 {
140-
/// Convert a data processing instruction into a 32-bit value.
113+
/// Convert an instruction into a 32-bit value.
141114
fn from(inst: DataProcessingImmediate) -> Self {
115+
let imm12 = (inst.imm12 as u32) & ((1 << 12) - 1);
116+
142117
0
143-
| (inst.sf as u32).wrapping_shl(31)
144-
| (inst.op as u32).wrapping_shl(30)
145-
| (inst.s as u32).wrapping_shl(29)
146-
| (Family::DataProcessingImmediate as u32).wrapping_shl(25)
147-
| (0b1 << 24)
148-
| (inst.shift as u32).wrapping_shl(22)
149-
| (inst.imm12 as u32).wrapping_shl(10)
150-
| (inst.rn as u32).wrapping_shl(5)
118+
| ((inst.sf as u32) << 31)
119+
| ((inst.op as u32) << 30)
120+
| ((inst.s as u32) << 29)
121+
| ((Family::DataProcessingImmediate as u32) << 25)
122+
| (1 << 24)
123+
| ((inst.shift as u32) << 22)
124+
| (imm12 << 10)
125+
| ((inst.rn as u32) << 5)
151126
| inst.rd as u32
152127
}
153128
}
154129

155130
impl From<DataProcessingImmediate> for [u8; 4] {
156-
/// Convert a data processing instruction into a 4 byte array.
131+
/// Convert an instruction into a 4 byte array.
157132
fn from(inst: DataProcessingImmediate) -> [u8; 4] {
158133
let result: u32 = inst.into();
159134
result.to_le_bytes()
@@ -166,32 +141,28 @@ mod tests {
166141

167142
#[test]
168143
fn test_add() {
169-
let uimm12 = A64Opnd::new_uimm(7);
170-
let inst = DataProcessingImmediate::add(&X0, &X1, &uimm12);
144+
let inst = DataProcessingImmediate::add(0, 1, 7, 64);
171145
let result: u32 = inst.into();
172146
assert_eq!(0x91001c20, result);
173147
}
174148

175149
#[test]
176150
fn test_adds() {
177-
let uimm12 = A64Opnd::new_uimm(7);
178-
let inst = DataProcessingImmediate::adds(&X0, &X1, &uimm12);
151+
let inst = DataProcessingImmediate::adds(0, 1, 7, 64);
179152
let result: u32 = inst.into();
180153
assert_eq!(0xb1001c20, result);
181154
}
182155

183156
#[test]
184157
fn test_sub() {
185-
let uimm12 = A64Opnd::new_uimm(7);
186-
let inst = DataProcessingImmediate::sub(&X0, &X1, &uimm12);
158+
let inst = DataProcessingImmediate::sub(0, 1, 7, 64);
187159
let result: u32 = inst.into();
188160
assert_eq!(0xd1001c20, result);
189161
}
190162

191163
#[test]
192164
fn test_subs() {
193-
let uimm12 = A64Opnd::new_uimm(7);
194-
let inst = DataProcessingImmediate::subs(&X0, &X1, &uimm12);
165+
let inst = DataProcessingImmediate::subs(0, 1, 7, 64);
195166
let result: u32 = inst.into();
196167
assert_eq!(0xf1001c20, result);
197168
}

0 commit comments

Comments
 (0)