Skip to content

Commit 7db7eec

Browse files
committed
more translations + builds now
1 parent 0cd2663 commit 7db7eec

5 files changed

Lines changed: 223 additions & 45 deletions

File tree

src/instruction.rs

Lines changed: 124 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::default;
2+
13
/// This file defines all the supported ARM and RISC-V instructions we support.
24
/// We use `strum` to assist in serializing asm files to our [`Instruction`] enum.
35
///
@@ -9,6 +11,13 @@
911
/// https://github.com/nbdd0121/r2vm/blob/5118be6b9e757c6fef2f019385873f403c23c548/lib/riscv/src/op.rs#L30
1012
use strum_macros::EnumString;
1113

14+
#[derive(Debug, Default)]
15+
pub enum RiscVWidth {
16+
Word,
17+
#[default]
18+
Double,
19+
}
20+
1221
/// RISC-V Instructions
1322
/// https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html
1423
///
@@ -26,39 +35,44 @@ pub enum RiscVInstruction {
2635
src: RiscVRegister,
2736
imm: i32,
2837
},
29-
/// Store 64-bit, values from register rs2 to memory.
38+
/// add register
39+
/// either add or addw
40+
/// (addw is 32 bits on 64 bit riscv)
41+
///
42+
/// `x[rd] = sext((x[rs1] + x[rs2])[31:0])`
43+
#[strum(serialize = "addw")]
44+
Add {
45+
// dest = arg1 + arg2
46+
width: RiscVWidth,
47+
dest: RiscVRegister,
48+
arg1: RiscVRegister,
49+
arg2: RiscVRegister,
50+
},
51+
/// Store values from register rs2 to memory.
3052
///
31-
/// `M[x[rs1] + sext(offset)] = x[rs2][63:0]`
53+
/// `M[x[rs1] + sext(offset)] = x[rs2]`
3254
#[strum(serialize = "sd")]
33-
Sd {
55+
S {
56+
width: RiscVWidth,
3457
src: RiscVRegister,
3558
dest: RiscVVal,
3659
},
37-
/// Loads a 64-bit value from memory into register rd for RV64I.
60+
/// Loads a value from memory into register rd for RV64I.
3861
///
39-
/// `x[rd] = M[x[rs1] + sext(offset)][63:0]`
62+
/// `x[rd] = M[x[rs1] + sext(offset)]`
4063
#[strum(serialize = "ld")]
41-
Ld { dest: RiscVRegister, src: RiscVVal },
42-
/// Loads a 32-bit value from memory and sign-extends this to XLEN bits
43-
/// before storing it in register rd.
44-
///
45-
/// `x[rd] = sext(M[x[rs1] + sext(offset)][31:0])`
46-
#[strum(serialize = "lw")]
47-
Lw { dest: RiscVRegister, src: RiscVVal },
48-
/// Store 32-bit, values from the low bits of register rs2 to memory.
49-
///
50-
/// `M[x[rs1] + sext(offset)] = x[rs2][31:0]`
51-
#[strum(serialize = "sw")]
52-
Sw { dest: RiscVRegister, src: RiscVVal },
64+
L {
65+
width: RiscVWidth,
66+
dest: RiscVRegister,
67+
src: RiscVVal,
68+
},
5369
// Copy register
5470
// `mv rd, rs1` expands to `addi rd, rs, 0`
5571
#[strum(serialize = "mv")]
5672
Mv {
5773
dest: RiscVRegister,
5874
src: RiscVRegister,
5975
},
60-
#[strum(serialize = "addw")]
61-
Addw,
6276
/// Sign extend Word
6377
///
6478
/// psuedo instruction which translates to `addiw rd, rs, 0`
@@ -67,6 +81,13 @@ pub enum RiscVInstruction {
6781
dest: RiscVRegister,
6882
src: RiscVRegister,
6983
},
84+
/// Jump Register
85+
/// Jump to address and place return address in rd.
86+
/// jal rd,offset
87+
///
88+
/// Psuedo instruction:
89+
/// jr offset => jal x1, offset
90+
///
7091
#[strum(serialize = "jr")]
7192
Jr { target: RiscVRegister },
7293
/// Load Immediate
@@ -79,7 +100,16 @@ pub enum RiscVInstruction {
79100
/// semantics.
80101
/// https://michaeljclark.github.io/asm.html
81102
#[strum(serialize = "li")]
82-
Li { imm: i32 },
103+
Li { dest: RiscVRegister, imm: i32 },
104+
}
105+
106+
impl Default for RiscVInstruction {
107+
fn default() -> Self {
108+
Self::Li {
109+
dest: RiscVRegister::X0,
110+
imm: 0,
111+
}
112+
}
83113
}
84114

85115
#[derive(Debug)]
@@ -89,6 +119,28 @@ pub enum ArmVal {
89119
RegOffset(ArmRegister, i32),
90120
}
91121

122+
impl Default for ArmVal {
123+
fn default() -> Self {
124+
todo!()
125+
}
126+
}
127+
128+
#[derive(Debug)]
129+
pub enum ArmWidth {
130+
Byte,
131+
SignedByte,
132+
Half,
133+
SignedHalf,
134+
Word,
135+
Double,
136+
}
137+
138+
impl Default for ArmWidth {
139+
fn default() -> Self {
140+
todo!()
141+
}
142+
}
143+
92144
/// ARM Instructions
93145
/// `https://iitd-plos.github.io/col718/ref/arm-instructionset.pdf#page=3`
94146
#[derive(Debug, EnumString)]
@@ -111,30 +163,47 @@ pub enum ArmInstruction {
111163
/// B Branch R15 := address
112164
#[strum(serialize = "b")]
113165
B,
166+
/// BLR Xn
167+
#[strum(serialize = "blr")]
168+
Blr { target: ArmRegisterName },
114169
#[strum(serialize = "ldr")]
115-
Ldr,
170+
Ldr {
171+
width: ArmWidth,
172+
dest: ArmRegister,
173+
src: ArmVal,
174+
},
116175
#[strum(serialize = "mov")]
117176
Mov,
118177
#[strum(serialize = "ret")]
119178
Ret,
120179
/// Str [r2 + offset] = r1
121180
#[strum(serialize = "str")]
122181
Str {
182+
width: ArmWidth,
123183
src: ArmRegister,
124-
dst: ArmVal,
125-
}
184+
dest: ArmVal,
185+
},
126186
/// Sub Sub Rd := Rn - Op2
127187
#[strum(serialize = "sub")]
128188
Sub {
129189
dest: ArmRegister,
130190
arg1: ArmRegister,
131191
arg2: ArmVal,
132192
},
193+
/// sign extend to word
194+
#[strum(serialize = "sxtw")]
195+
Sxtw { dest: ArmRegister, src: ArmRegister },
196+
}
197+
198+
impl Default for ArmInstruction {
199+
fn default() -> Self {
200+
ArmInstruction::B
201+
}
133202
}
134203

135204
#[derive(Debug)]
136205
pub enum RiscVVal {
137-
RiscVRegister,
206+
RiscVRegister(RiscVRegister),
138207
Immediate(i32),
139208
/// This is for arguments to opcodes which have an offset
140209
Offset {
@@ -143,10 +212,17 @@ pub enum RiscVVal {
143212
},
144213
}
145214

215+
impl Default for RiscVVal {
216+
fn default() -> Self {
217+
Self::Immediate(0)
218+
}
219+
}
220+
146221
/// RISC-V Registers
147222
/// https://msyksphinz-self.github.io/riscv-isadoc/html/regs.html
148-
#[derive(Debug, EnumString)]
223+
#[derive(Debug, EnumString, Default)]
149224
pub enum RiscVRegister {
225+
#[default]
150226
#[strum(serialize = "x0")]
151227
/// Hard-wired zero
152228
X0,
@@ -245,10 +321,22 @@ pub enum RiscVRegister {
245321
T6,
246322
}
247323

324+
#[derive(Debug)]
325+
pub struct ArmRegister {
326+
pub width: ArmWidth,
327+
pub name: ArmRegisterName,
328+
}
329+
330+
impl Default for ArmRegister {
331+
fn default() -> Self {
332+
todo!()
333+
}
334+
}
335+
248336
/// ARM Registers
249337
/// https://developer.arm.com/documentation/dui0056/d/using-the-procedure-call-standard/register-roles-and-names/register-names
250338
#[derive(Debug, EnumString)]
251-
pub enum ArmRegister {
339+
pub enum ArmRegisterName {
252340
#[strum(serialize = "pc")]
253341
/// Program counter.
254342
Pc,
@@ -297,6 +385,14 @@ pub enum ArmRegister {
297385
#[strum(serialize = "a1")]
298386
/// Argument/result/scratch register 1.
299387
A1,
388+
#[strum(serialize = "wzr", serialize = "xzr")]
389+
Zero,
390+
}
391+
392+
impl Default for ArmRegisterName {
393+
fn default() -> Self {
394+
todo!()
395+
}
300396
}
301397

302398
/// Parse a text file into our enum.
@@ -310,7 +406,8 @@ pub fn parse_asm(asm: &str) -> Vec<RiscVInstruction> {
310406
if parts.is_empty() {
311407
None
312408
} else {
313-
RiscVInstruction::from_str(parts[0]).ok()
409+
// RiscVInstruction::from_str(parts[0]).ok()
410+
todo!()
314411
}
315412
})
316413
.collect()

src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use std::str::FromStr;
33
pub mod instruction;
44
pub mod translate;
55
use instruction::RiscVInstruction;
6-
7-
6+
use translate::binary_translate;
87

98
// Samir: I am using main for testing, but it not needed since you can run
109
// `cargo test` instead.

0 commit comments

Comments
 (0)