Skip to content

Commit 2c692d6

Browse files
committed
call syscall
1 parent 6fa93ff commit 2c692d6

3 files changed

Lines changed: 227 additions & 28 deletions

File tree

src/instruction.rs

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::convert::Into;
22
use std::default;
3-
use std::fmt::{write, Display};
3+
use std::fmt::{format, write, Display};
44

55
/// This file defines all the supported ARM and RISC-V instructions we support.
66
/// We use `strum` to assist in serializing asm files to our [`Instruction`] enum.
@@ -37,6 +37,12 @@ pub enum RiscVInstruction {
3737
src: RiscVRegister,
3838
imm: i32,
3939
},
40+
/// add label/offset addr (not a real RISC-V instr)
41+
Addl {
42+
dest: RiscVRegister,
43+
src: RiscVRegister,
44+
label: RiscVVal
45+
},
4046
/// add register
4147
/// either add or addw
4248
/// (addw is 32 bits on 64 bit riscv)
@@ -50,6 +56,11 @@ pub enum RiscVInstruction {
5056
arg1: RiscVRegister,
5157
arg2: RiscVRegister,
5258
},
59+
/// call label
60+
#[strum(serialize = "call")]
61+
Call {
62+
label: RiscVVal
63+
},
5364
/// Store values from register rs2 to memory.
5465
///
5566
/// `M[x[rs1] + sext(offset)] = x[rs2]`
@@ -68,6 +79,18 @@ pub enum RiscVInstruction {
6879
dest: RiscVRegister,
6980
src: RiscVVal,
7081
},
82+
Directive {
83+
name: String,
84+
operands: String
85+
},
86+
Label {
87+
name: String
88+
},
89+
#[strum(serialize = "lui")]
90+
Lui {
91+
dest: RiscVRegister,
92+
src: RiscVVal
93+
},
7194
// Copy register
7295
// `mv rd, rs1` expands to `addi rd, rs, 0`
7396
#[strum(serialize = "mv")]
@@ -126,6 +149,7 @@ pub enum ArmVal {
126149
Reg(ArmRegister),
127150
Imm(i32),
128151
RegOffset(ArmRegister, i32),
152+
LabelOffset(String, i32)
129153
}
130154

131155
impl Default for ArmVal {
@@ -169,12 +193,28 @@ pub enum ArmInstruction {
169193
/// AND AND Rd := Rn AND Op2
170194
#[strum(serialize = "and")]
171195
And,
196+
/// ADRP Rd := page_addr(label)
197+
#[strum(serialize = "adrp")]
198+
Adrp {
199+
dest: ArmRegister,
200+
label: ArmVal
201+
},
172202
/// B Branch R15 := address
173203
#[strum(serialize = "b")]
174204
B,
175205
/// BLR Xn
176206
#[strum(serialize = "blr")]
177207
Blr { target: ArmRegisterName },
208+
/// BL label
209+
#[strum(serialize = "bl")]
210+
Bl {target: ArmVal},
211+
/// label:
212+
Label { name: String },
213+
/// .directive operands
214+
Directive {
215+
name: String,
216+
operands: String
217+
},
178218
#[strum(serialize = "ldr")]
179219
Ldr {
180220
width: ArmWidth,
@@ -223,6 +263,10 @@ pub enum RiscVVal {
223263
register: RiscVRegister,
224264
offset: i32,
225265
},
266+
LabelOffset {
267+
label: String,
268+
offset: i32
269+
}
226270
}
227271

228272
impl Default for RiscVVal {
@@ -436,6 +480,9 @@ impl Into<String> for ArmInstruction {
436480
format!("add {}, {}, {}", dest, arg1, arg2)
437481
},
438482
ArmInstruction::And => todo!(),
483+
ArmInstruction::Adrp { dest, label } => {
484+
format!("adrp {}, {}", dest, label)
485+
}
439486
ArmInstruction::B => todo!(),
440487
ArmInstruction::Blr { target } => {
441488
format!("blr {}", Into::<ArmRegister>::into(target))
@@ -464,6 +511,15 @@ impl Into<String> for ArmInstruction {
464511
ArmInstruction::Sxtw { dest, src } => {
465512
format!("sxtw {}, {}", dest, src)
466513
},
514+
ArmInstruction::Bl { target } => {
515+
format!("bl {}", target)
516+
},
517+
ArmInstruction::Label { name } => {
518+
format!("{}:", name)
519+
},
520+
ArmInstruction::Directive { name, operands } => {
521+
format!(".{} {}", name, operands)
522+
}
467523
}
468524
}
469525
}
@@ -500,26 +556,26 @@ impl Into<String> for ArmRegister {
500556
(ArmRegisterName::X1, ArmWidth::SignedByte) => todo!(),
501557
(ArmRegisterName::X1, ArmWidth::Half) => todo!(),
502558
(ArmRegisterName::X1, ArmWidth::SignedHalf) => todo!(),
503-
(ArmRegisterName::X1, ArmWidth::Word) => todo!(),
504-
(ArmRegisterName::X1, ArmWidth::Double) => todo!(),
559+
(ArmRegisterName::X1, ArmWidth::Word) => "w1",
560+
(ArmRegisterName::X1, ArmWidth::Double) => "x1",
505561
(ArmRegisterName::X2, ArmWidth::Byte) => todo!(),
506562
(ArmRegisterName::X2, ArmWidth::SignedByte) => todo!(),
507563
(ArmRegisterName::X2, ArmWidth::Half) => todo!(),
508564
(ArmRegisterName::X2, ArmWidth::SignedHalf) => todo!(),
509-
(ArmRegisterName::X2, ArmWidth::Word) => todo!(),
510-
(ArmRegisterName::X2, ArmWidth::Double) => todo!(),
565+
(ArmRegisterName::X2, ArmWidth::Word) => "w2",
566+
(ArmRegisterName::X2, ArmWidth::Double) => "x2",
511567
(ArmRegisterName::X3, ArmWidth::Byte) => todo!(),
512568
(ArmRegisterName::X3, ArmWidth::SignedByte) => todo!(),
513569
(ArmRegisterName::X3, ArmWidth::Half) => todo!(),
514570
(ArmRegisterName::X3, ArmWidth::SignedHalf) => todo!(),
515-
(ArmRegisterName::X3, ArmWidth::Word) => todo!(),
516-
(ArmRegisterName::X3, ArmWidth::Double) => todo!(),
571+
(ArmRegisterName::X3, ArmWidth::Word) => "w3",
572+
(ArmRegisterName::X3, ArmWidth::Double) => "x3",
517573
(ArmRegisterName::X4, ArmWidth::Byte) => todo!(),
518574
(ArmRegisterName::X4, ArmWidth::SignedByte) => todo!(),
519575
(ArmRegisterName::X4, ArmWidth::Half) => todo!(),
520576
(ArmRegisterName::X4, ArmWidth::SignedHalf) => todo!(),
521-
(ArmRegisterName::X4, ArmWidth::Word) => todo!(),
522-
(ArmRegisterName::X4, ArmWidth::Double) => todo!(),
577+
(ArmRegisterName::X4, ArmWidth::Word) => "w4",
578+
(ArmRegisterName::X4, ArmWidth::Double) => "x4",
523579
(ArmRegisterName::X5, ArmWidth::Byte) => todo!(),
524580
(ArmRegisterName::X5, ArmWidth::SignedByte) => todo!(),
525581
(ArmRegisterName::X5, ArmWidth::Half) => todo!(),
@@ -696,6 +752,14 @@ impl Display for ArmVal {
696752
};
697753
write!(f, "[{}, {}]", double_reg, offset)
698754
},
755+
ArmVal::LabelOffset(name, offset) => {
756+
match offset {
757+
0 => write!(f, "{}", name),
758+
9998 => write!(f, "{}", name), // %hi in riscv is adrp with no offset in arm
759+
9999 => write!(f, ":lo12:{}", name), // reserved for 12 low bits of label addr
760+
_ => write!(f, "[{}, {}]", name, offset)
761+
}
762+
}
699763
}
700764
}
701765
}

src/translate.rs

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,27 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
4646
dest: map_register(dest, &width),
4747
src: map_val(src, &width),
4848
},
49-
RiscVInstruction::Mv { dest, src } => {
49+
RiscVInstruction::Directive { name, operands } => {
50+
let arm_operands = operands.replace("@", "%");
51+
ArmInstruction::Directive { name, operands: arm_operands }
52+
}
53+
RiscVInstruction::Label { name } => ArmInstruction::Label { name },
54+
RiscVInstruction::Mv { dest, src } => {
5055
let width = RiscVWidth::Double;
5156
ArmInstruction::Add {
5257
dest: map_register(dest, &width),
5358
arg1: map_register(src, &width),
5459
arg2: ArmVal::Imm(0),
5560
}
56-
},
57-
RiscVInstruction::Mvi { dest, imm } => {
61+
}
62+
RiscVInstruction::Mvi { dest, imm } => {
5863
let width = RiscVWidth::Double;
5964
ArmInstruction::Mov {
6065
width: map_width(&width),
6166
dest: map_register(dest, &width),
62-
src: ArmVal::Imm(imm)
67+
src: ArmVal::Imm(imm),
6368
}
64-
},
69+
}
6570
RiscVInstruction::Add {
6671
width,
6772
dest,
@@ -103,10 +108,10 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
103108
}
104109

105110
let width = RiscVWidth::Double;
106-
ArmInstruction::Mov {
107-
width: map_width(&width),
108-
dest: map_register(dest, &width),
109-
src: ArmVal::Imm(imm)
111+
ArmInstruction::Mov {
112+
width: map_width(&width),
113+
dest: map_register(dest, &width),
114+
src: ArmVal::Imm(imm),
110115
}
111116
// ArmInstruction::Add {
112117
// dest: map_register(dest, &RiscVWidth::Double),
@@ -116,14 +121,36 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
116121
// },
117122
// arg2: ArmVal::Imm(imm),
118123
// }
124+
},
125+
RiscVInstruction::Addl { dest, src, label } => {
126+
let width = RiscVWidth::Double;
127+
ArmInstruction::Add {
128+
dest: map_register(dest, &width),
129+
arg1: map_register(src, &width),
130+
arg2: map_val(label, &width),
131+
}
132+
},
133+
RiscVInstruction::Lui { dest, src } => {
134+
// only used to load upper bits or adrp in arm
135+
let width = RiscVWidth::Double;
136+
ArmInstruction::Adrp {
137+
dest: map_register(dest, &width),
138+
label: map_val(src, &width),
139+
}
140+
},
141+
RiscVInstruction::Call { label } => {
142+
let width = RiscVWidth::Double;
143+
ArmInstruction::Bl {
144+
target: map_val(label, &width),
145+
}
119146
}
120147
}
121148
}
122149

123150
fn map_register(riscv_reg: RiscVRegister, riscv_width: &RiscVWidth) -> ArmRegister {
124151
ArmRegister {
125152
width: map_width(riscv_width),
126-
name: map_register_name(riscv_reg)
153+
name: map_register_name(riscv_reg),
127154
}
128155
}
129156

@@ -142,13 +169,13 @@ fn map_register_name(riscv_reg: RiscVRegister) -> ArmRegisterName {
142169
// skipped X5
143170
RiscVRegister::S1 => ArmRegisterName::X6,
144171
RiscVRegister::A0 => ArmRegisterName::X0,
145-
RiscVRegister::A1 => ArmRegisterName::X8,
146-
RiscVRegister::A2 => ArmRegisterName::X9,
147-
RiscVRegister::A3 => ArmRegisterName::X10,
148-
RiscVRegister::A4 => ArmRegisterName::X11,
149-
RiscVRegister::A5 => ArmRegisterName::X12,
150-
RiscVRegister::A6 => ArmRegisterName::X13,
151-
RiscVRegister::A7 => ArmRegisterName::X14,
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,
152179
RiscVRegister::S2 => ArmRegisterName::X15,
153180
RiscVRegister::S3 => ArmRegisterName::X16,
154181
RiscVRegister::S4 => ArmRegisterName::X17,
@@ -172,15 +199,16 @@ fn map_val(riscv_val: RiscVVal, riscv_width: &RiscVWidth) -> ArmVal {
172199
RiscVVal::RiscVRegister(riscv_reg) => ArmVal::Reg(map_register(riscv_reg, riscv_width)),
173200
RiscVVal::Immediate(imm) => ArmVal::Imm(imm),
174201
RiscVVal::Offset { register, offset } => ArmVal::RegOffset(map_register(register, riscv_width), offset),
202+
RiscVVal::LabelOffset { label, offset } => ArmVal::LabelOffset(label, offset),
175203
}
176204
}
177205

178206
fn map_width(riscv_width: &RiscVWidth) -> ArmWidth {
179207
// todo!()
180-
// FIXME: do real implementation
208+
// FIXME: do real implementation
181209
match riscv_width {
182210
RiscVWidth::Double => ArmWidth::Double,
183-
RiscVWidth::Word => ArmWidth::Word
211+
RiscVWidth::Word => ArmWidth::Word,
184212
}
185213
}
186214

0 commit comments

Comments
 (0)