Skip to content

Commit b02600a

Browse files
committed
merge and working print
1 parent 2c692d6 commit b02600a

10 files changed

Lines changed: 218 additions & 72 deletions

File tree

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
];
3636
packages = with pkgs; [
3737
rust-analyzer-nightly
38+
clang-tools
3839
];
3940
};
4041
}

run.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env bash
22

3-
aarch64-linux-gnu-as test_binary_translate_add.S
4-
aarch64-linux-gnu-ld a.out -o a.bin
5-
./a.bin
3+
ASM_FILE=$1
4+
5+
6+
aarch64-linux-gnu-as $ASM_FILE -o $ASM_FILE.as
7+
aarch64-linux-gnu-ld $ASM_FILE.as -o $ASM_FILE.bin
8+
./$ASM_FILE.bin
69
echo $?

src/instruction.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ use std::fmt::{format, write, Display};
1313
/// https://github.com/nbdd0121/r2vm/blob/5118be6b9e757c6fef2f019385873f403c23c548/lib/riscv/src/op.rs#L30
1414
use strum_macros::EnumString;
1515

16+
pub enum RiscVSyscalls {
17+
WRITE,
18+
EXIT
19+
}
20+
21+
impl RiscVSyscalls {
22+
const fn value(&self) -> i32 {
23+
match self {
24+
Self::WRITE => 64,
25+
Self::EXIT => 0,
26+
}
27+
}
28+
}
29+
1630
#[derive(Debug, Default)]
1731
pub enum RiscVWidth {
1832
Word,
@@ -133,6 +147,11 @@ pub enum RiscVInstruction {
133147
/// https://michaeljclark.github.io/asm.html
134148
#[strum(serialize = "li")]
135149
Li { dest: RiscVRegister, imm: i32 },
150+
/// System Call
151+
#[strum(serialize = "ecall")]
152+
ECall,
153+
#[strum(serialize = "verbatim")]
154+
Verbatim { text: String },
136155
}
137156

138157
impl Default for RiscVInstruction {
@@ -144,6 +163,20 @@ impl Default for RiscVInstruction {
144163
}
145164
}
146165

166+
pub enum ArmSyscalls {
167+
WRITE,
168+
EXIT
169+
}
170+
171+
impl ArmSyscalls {
172+
const fn value(&self) -> i32 {
173+
match self {
174+
Self::WRITE => 64,
175+
Self::EXIT => 0,
176+
}
177+
}
178+
}
179+
147180
#[derive(Debug)]
148181
pub enum ArmVal {
149182
Reg(ArmRegister),
@@ -246,6 +279,12 @@ pub enum ArmInstruction {
246279
/// sign extend to word
247280
#[strum(serialize = "sxtw")]
248281
Sxtw { dest: ArmRegister, src: ArmRegister },
282+
/// service call
283+
#[strum(serialize = "svc")]
284+
Svc { id: i32 },
285+
/// compare
286+
Cmp { op1: ArmRegister, op2: ArmVal },
287+
Verbatim { text: String },
249288
}
250289

251290
impl Default for ArmInstruction {
@@ -520,6 +559,13 @@ impl Into<String> for ArmInstruction {
520559
ArmInstruction::Directive { name, operands } => {
521560
format!(".{} {}", name, operands)
522561
}
562+
ArmInstruction::Svc { id } => {
563+
format!("svc {}", id)
564+
},
565+
ArmInstruction::Cmp { op1, op2 } => {
566+
format!("cmp {}, {}", op1, op2)
567+
}
568+
ArmInstruction::Verbatim { text } => text
523569
}
524570
}
525571
}
@@ -599,7 +645,7 @@ impl Into<String> for ArmRegister {
599645
(ArmRegisterName::X8, ArmWidth::Half) => todo!(),
600646
(ArmRegisterName::X8, ArmWidth::SignedHalf) => todo!(),
601647
(ArmRegisterName::X8, ArmWidth::Word) => todo!(),
602-
(ArmRegisterName::X8, ArmWidth::Double) => todo!(),
648+
(ArmRegisterName::X8, ArmWidth::Double) => "x8",
603649
(ArmRegisterName::X9, ArmWidth::Byte) => todo!(),
604650
(ArmRegisterName::X9, ArmWidth::SignedByte) => todo!(),
605651
(ArmRegisterName::X9, ArmWidth::Half) => todo!(),

src/translate.rs

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ macro_rules! sorry {
1414
/// Run the core logic to match from RISC-V to ARM Instructions.
1515
1616
/// Translate one instruction at a time.
17-
pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
17+
pub fn translate(riscv_instr: RiscVInstruction) -> Vec<ArmInstruction> {
1818
match riscv_instr {
1919
RiscVInstruction::Addi { dest, src, imm } => {
2020
if let RiscVRegister::X0 = src {
@@ -23,57 +23,57 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
2323

2424
let width = RiscVWidth::Double;
2525
if imm >= 0 {
26-
ArmInstruction::Add {
26+
vec![ArmInstruction::Add {
2727
dest: map_register(dest, &width),
2828
arg1: map_register(src, &width),
2929
arg2: ArmVal::Imm(imm),
30-
}
30+
}]
3131
} else {
32-
ArmInstruction::Sub {
32+
vec![ArmInstruction::Sub {
3333
dest: map_register(dest, &width),
3434
arg1: map_register(src, &width),
3535
arg2: ArmVal::Imm(imm.abs()),
36-
}
36+
}]
3737
}
3838
}
39-
RiscVInstruction::S { width, src, dest } => ArmInstruction::Str {
39+
RiscVInstruction::S { width, src, dest } => vec![ArmInstruction::Str {
4040
width: map_width(&width),
4141
src: map_register(src, &width),
4242
dest: map_val(dest, &width),
43-
},
44-
RiscVInstruction::L { width, dest, src } => ArmInstruction::Ldr {
43+
}],
44+
RiscVInstruction::L { width, dest, src } => vec![ArmInstruction::Ldr {
4545
width: map_width(&width),
4646
dest: map_register(dest, &width),
4747
src: map_val(src, &width),
48-
},
48+
}],
4949
RiscVInstruction::Directive { name, operands } => {
5050
let arm_operands = operands.replace("@", "%");
51-
ArmInstruction::Directive { name, operands: arm_operands }
51+
vec![ArmInstruction::Directive { name, operands: arm_operands }]
5252
}
53-
RiscVInstruction::Label { name } => ArmInstruction::Label { name },
53+
RiscVInstruction::Label { name } => vec![ArmInstruction::Label { name }],
5454
RiscVInstruction::Mv { dest, src } => {
5555
let width = RiscVWidth::Double;
56-
ArmInstruction::Add {
56+
vec![ArmInstruction::Add {
5757
dest: map_register(dest, &width),
5858
arg1: map_register(src, &width),
5959
arg2: ArmVal::Imm(0),
60-
}
61-
}
62-
RiscVInstruction::Mvi { dest, imm } => {
60+
}]
61+
},
62+
RiscVInstruction::Mvi { dest, imm } => {
6363
let width = RiscVWidth::Double;
64-
ArmInstruction::Mov {
64+
vec![ArmInstruction::Mov {
6565
width: map_width(&width),
6666
dest: map_register(dest, &width),
67-
src: ArmVal::Imm(imm),
68-
}
69-
}
67+
src: ArmVal::Imm(imm)
68+
}]
69+
},
7070
RiscVInstruction::Add {
7171
width,
7272
dest,
7373
arg1,
7474
arg2,
7575
} => match width {
76-
RiscVWidth::Word => ArmInstruction::Add {
76+
RiscVWidth::Word => vec![ArmInstruction::Add {
7777
dest: ArmRegister {
7878
width: ArmWidth::Word,
7979
name: map_register_name(dest),
@@ -86,10 +86,10 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
8686
width: ArmWidth::Word,
8787
name: map_register_name(arg2),
8888
}),
89-
},
89+
}],
9090
RiscVWidth::Double => sorry!(),
9191
},
92-
RiscVInstruction::SextW { dest, src } => ArmInstruction::Sxtw {
92+
RiscVInstruction::SextW { dest, src } => vec![ArmInstruction::Sxtw {
9393
dest: ArmRegister {
9494
width: ArmWidth::Double,
9595
name: map_register_name(dest),
@@ -98,21 +98,21 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
9898
width: ArmWidth::Word,
9999
name: map_register_name(src),
100100
},
101-
},
102-
RiscVInstruction::Jr { target } => ArmInstruction::Blr {
101+
}],
102+
RiscVInstruction::Jr { target } => vec![ArmInstruction::Blr {
103103
target: map_register_name(target),
104-
},
104+
}],
105105
RiscVInstruction::Li { dest, imm } => {
106106
if imm > 4095 || imm < 0 {
107107
panic!("Li with imm out of range");
108108
}
109109

110110
let width = RiscVWidth::Double;
111-
ArmInstruction::Mov {
111+
vec![ArmInstruction::Mov {
112112
width: map_width(&width),
113113
dest: map_register(dest, &width),
114114
src: ArmVal::Imm(imm),
115-
}
115+
}]
116116
// ArmInstruction::Add {
117117
// dest: map_register(dest, &RiscVWidth::Double),
118118
// arg1: ArmRegister {
@@ -124,26 +124,44 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
124124
},
125125
RiscVInstruction::Addl { dest, src, label } => {
126126
let width = RiscVWidth::Double;
127-
ArmInstruction::Add {
127+
vec![ArmInstruction::Add {
128128
dest: map_register(dest, &width),
129129
arg1: map_register(src, &width),
130130
arg2: map_val(label, &width),
131-
}
131+
}]
132132
},
133133
RiscVInstruction::Lui { dest, src } => {
134134
// only used to load upper bits or adrp in arm
135135
let width = RiscVWidth::Double;
136-
ArmInstruction::Adrp {
136+
vec![ArmInstruction::Adrp {
137137
dest: map_register(dest, &width),
138138
label: map_val(src, &width),
139-
}
139+
}]
140140
},
141141
RiscVInstruction::Call { label } => {
142142
let width = RiscVWidth::Double;
143-
ArmInstruction::Bl {
143+
vec![ArmInstruction::Bl {
144144
target: map_val(label, &width),
145-
}
145+
}]
146+
}
147+
RiscVInstruction::ECall => {
148+
let syscall_num_reg = ArmRegister{
149+
width: ArmWidth::Double,
150+
name: ArmRegisterName::X8
151+
};
152+
vec![
153+
// ArmInstruction::Cmp(syscall_num_reg, ArmVal::Imm(RISCV_WRITE)), // if (x8 == RISCV_WRITE) {
154+
// ArmInstruction::Bne("else"),
155+
// ArmInstruction::Mov { width: ArmWidth::Double, dest: x8, src: ArmVal::Imm(SYS_WRITE) }, // x8 = ARM_WRITE;
156+
// ArmInstruction::B("done"),
157+
// ArmInstruction::Label("else"), // } else {
158+
// ArmInstruction::Mov { width: ArmWidth::Double, dest: x8, src: ArmVal::Imm(__) }, // x8 = ARM_EXIT
159+
// // }
160+
// ArmInstruction::Label("done"),
161+
ArmInstruction::Svc { id: 0 }
162+
]
146163
}
164+
RiscVInstruction::Verbatim { text } => vec![ArmInstruction::Verbatim { text }]
147165
}
148166
}
149167

@@ -161,21 +179,30 @@ fn map_register_name(riscv_reg: RiscVRegister) -> ArmRegisterName {
161179
RiscVRegister::X0 => ArmRegisterName::Zero,
162180
RiscVRegister::RA => ArmRegisterName::Lr,
163181
RiscVRegister::SP => ArmRegisterName::Sp,
164-
RiscVRegister::GP => ArmRegisterName::X0,
165-
RiscVRegister::TP => ArmRegisterName::X1,
166-
RiscVRegister::T0 => ArmRegisterName::X2,
167-
RiscVRegister::T1 => ArmRegisterName::X3,
168-
RiscVRegister::T2 => ArmRegisterName::X4,
182+
RiscVRegister::GP => ArmRegisterName::X12,
183+
RiscVRegister::TP => ArmRegisterName::X14,
184+
RiscVRegister::T0 => ArmRegisterName::X9,
185+
RiscVRegister::T1 => ArmRegisterName::X10,
186+
RiscVRegister::T2 => ArmRegisterName::X11,
169187
// skipped X5
170-
RiscVRegister::S1 => ArmRegisterName::X6,
171-
RiscVRegister::A0 => ArmRegisterName::X0,
172-
RiscVRegister::A1 => ArmRegisterName::X1,
173-
RiscVRegister::A2 => ArmRegisterName::X2,
174-
RiscVRegister::A3 => ArmRegisterName::X3,
175-
RiscVRegister::A4 => ArmRegisterName::X4,
176-
RiscVRegister::A5 => ArmRegisterName::X5,
177-
RiscVRegister::A6 => ArmRegisterName::X6,
178-
RiscVRegister::A7 => ArmRegisterName::X7,
188+
// RiscVRegister::S1 => ArmRegisterName::X6,
189+
// RiscVRegister::A0 => ArmRegisterName::X0,
190+
// RiscVRegister::A1 => ArmRegisterName::X1,
191+
// RiscVRegister::A2 => ArmRegisterName::X2,
192+
// RiscVRegister::A3 => ArmRegisterName::X3,
193+
// RiscVRegister::A4 => ArmRegisterName::X4,
194+
// RiscVRegister::A5 => ArmRegisterName::X5,
195+
// RiscVRegister::A6 => ArmRegisterName::X6,
196+
// RiscVRegister::A7 => ArmRegisterName::X7,
197+
RiscVRegister::S1 => ArmRegisterName::X13,
198+
RiscVRegister::A0 => ArmRegisterName::X0, // return value/syscall arg 0
199+
RiscVRegister::A1 => ArmRegisterName::X1, // syscall arg 1
200+
RiscVRegister::A2 => ArmRegisterName::X2, // syscall arg 2
201+
RiscVRegister::A3 => ArmRegisterName::X3, // syscall arg 3
202+
RiscVRegister::A4 => ArmRegisterName::X4, // syscall arg 4
203+
RiscVRegister::A5 => ArmRegisterName::X5, // syscall arg 5
204+
RiscVRegister::A6 => ArmRegisterName::X6, // syscall arg 6
205+
RiscVRegister::A7 => ArmRegisterName::X8, // syscall number
179206
RiscVRegister::S2 => ArmRegisterName::X15,
180207
RiscVRegister::S3 => ArmRegisterName::X16,
181208
RiscVRegister::S4 => ArmRegisterName::X17,
@@ -216,8 +243,10 @@ fn map_width(riscv_width: &RiscVWidth) -> ArmWidth {
216243
pub fn translate_instrs(riscv_instrs: Vec<RiscVInstruction>) -> Vec<ArmInstruction> {
217244
riscv_instrs
218245
.into_iter()
219-
.map(|instr| translate(instr))
220-
.collect::<Vec<ArmInstruction>>()
246+
.map(translate).fold(vec![], |mut acc, x|{
247+
acc.extend(x);
248+
acc
249+
})
221250
}
222251

223252
/// Runs binary translation

src/utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fs;
22

33
use crate::{instruction::RiscVInstruction, translate::translate_instrs};
44

5-
const start: &str = r#"
5+
pub const START: &str = r#"
66
.text
77
88
.global _start
@@ -15,9 +15,10 @@ svc #0
1515
main:
1616
"#;
1717

18+
1819
pub fn translate_to_file(instrs: Vec<RiscVInstruction>, path: String) {
1920
let arm_instrs = translate_instrs(instrs);
20-
let mut contents = String::from(start);
21+
let mut contents = String::new();
2122
for instr in arm_instrs {
2223
let x: String = instr.into();
2324
contents.push_str(&x);

0 commit comments

Comments
 (0)