Skip to content

Commit 7f93a02

Browse files
committed
Merge branch 'register-enum-translation' of github.com:Samir-Rashid/binary-room into register-enum-translation
2 parents 550b8d8 + 7a5d205 commit 7f93a02

2 files changed

Lines changed: 115 additions & 113 deletions

File tree

src/instruction.rs

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ pub enum RiscVRegister {
248248
/// Temporaries
249249
T2,
250250
#[strum(serialize = "s0", serialize = "fp")]
251-
/// Saved register/frame pointer
251+
/// Saved register/frame pointer R29
252252
S0FP,
253253
#[strum(serialize = "s1")]
254254
/// Saved registers
@@ -335,58 +335,60 @@ impl Default for ArmRegister {
335335

336336
/// ARM Registers
337337
/// https://developer.arm.com/documentation/dui0056/d/using-the-procedure-call-standard/register-roles-and-names/register-names
338+
/// Image of instructions https://duetorun.com/blog/arm/images/AArch64-registers.png
339+
/// - https://duetorun.com/blog/20230601/a64-regs/#user_program_registers
338340
#[derive(Debug, EnumString)]
339341
pub enum ArmRegisterName {
342+
#[strum(serialize = "wzr", serialize = "xzr")]
343+
/// Zero register. Hardware special.
344+
Zero,
340345
#[strum(serialize = "pc")]
341-
/// Program counter.
346+
/// Program counter. Hardware special register.
342347
Pc,
343-
#[strum(serialize = "lr")]
344-
/// Link register.
345-
Lr,
346348
#[strum(serialize = "sp")]
347-
/// Stack pointer.
349+
/// Stack pointer. Hardware special register.
348350
Sp,
349-
#[strum(serialize = "ip")]
350-
/// Intra-procedure-call scratch register.
351-
Ip,
352-
#[strum(serialize = "v8")]
353-
/// ARM-state variable register 8.
354-
V8,
355-
#[strum(serialize = "sl")]
356-
/// ARM-state variable register 7. Stack limit pointer in stack-checked variants.
357-
Sl,
358-
#[strum(serialize = "sb")]
359-
/// ARM-state variable register 6. Static base in RWPI variants.
360-
Sb,
361-
#[strum(serialize = "v5")]
362-
/// ARM-state variable register 5.
363-
V5,
364-
#[strum(serialize = "v4")]
365-
/// Variable register 4.
366-
V4,
367-
#[strum(serialize = "v3")]
368-
/// Variable register 3.
369-
V3,
370-
#[strum(serialize = "v2")]
371-
/// Variable register 2.
372-
V2,
373-
#[strum(serialize = "v1")]
374-
/// Variable register 1.
375-
V1,
376-
#[strum(serialize = "a4")]
377-
/// Argument/result/scratch register 4.
378-
A4,
379-
#[strum(serialize = "a3")]
380-
/// Argument/result/scratch register 3.
381-
A3,
382-
#[strum(serialize = "a2")]
383-
/// Argument/result/scratch register 2.
384-
A2,
385-
#[strum(serialize = "a1")]
386-
/// Argument/result/scratch register 1.
387-
A1,
388-
#[strum(serialize = "wzr", serialize = "xzr")]
389-
Zero,
351+
#[strum(serialize = "lr")]
352+
/// Link register. X30. Hardware special register.
353+
Lr,
354+
// Parameter passing and/or scratch registers (volatile)
355+
X0,
356+
X1,
357+
X2,
358+
X3,
359+
X4,
360+
X5,
361+
X6,
362+
X7,
363+
// Caller-Saved scratch registers (volatile)
364+
/// XR
365+
X8,
366+
X9,
367+
X10,
368+
X11,
369+
X12,
370+
X13,
371+
X14,
372+
X15,
373+
/// IP0
374+
X16,
375+
/// IP1
376+
X17,
377+
/// PR
378+
X18,
379+
// Caller-Saved registers (non-volatile)
380+
X19,
381+
X20,
382+
X21,
383+
X22,
384+
X23,
385+
X24,
386+
X25,
387+
X26,
388+
X27,
389+
X28,
390+
/// FP
391+
X29,
390392
}
391393

392394
impl Default for ArmRegisterName {

src/translate.rs

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,38 @@ macro_rules! sorry {
1717
pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
1818
match riscv_instr {
1919
RiscVInstruction::Addi { dest, src, imm } => {
20+
let width = RiscVWidth::Word;
2021
if imm >= 0 {
2122
ArmInstruction::Add {
22-
dest: map_register(dest),
23-
arg1: map_register(src),
23+
dest: map_register(dest, &width),
24+
arg1: map_register(src, &width),
2425
arg2: ArmVal::Imm(imm),
2526
}
2627
} else {
2728
ArmInstruction::Sub {
28-
dest: map_register(dest),
29-
arg1: map_register(src),
29+
dest: map_register(dest, &width),
30+
arg1: map_register(src, &width),
3031
arg2: ArmVal::Imm(imm),
3132
}
3233
}
3334
}
3435
RiscVInstruction::S { width, src, dest } => ArmInstruction::Str {
35-
width: map_width(width),
36-
src: map_register(src),
37-
dest: map_val(dest),
36+
width: map_width(&width),
37+
src: map_register(src, &width),
38+
dest: map_val(dest, &width),
3839
},
3940
RiscVInstruction::L { width, dest, src } => ArmInstruction::Ldr {
40-
width: map_width(width),
41-
dest: map_register(dest),
42-
src: map_val(src),
41+
width: map_width(&width),
42+
dest: map_register(dest, &width),
43+
src: map_val(src, &width),
4344
},
44-
RiscVInstruction::Mv { dest, src } => ArmInstruction::Add {
45-
dest: map_register(dest),
46-
arg1: map_register(src),
47-
arg2: ArmVal::Imm(0),
45+
RiscVInstruction::Mv { dest, src } => {
46+
let width = RiscVWidth::Double;
47+
ArmInstruction::Add {
48+
dest: map_register(dest, &width),
49+
arg1: map_register(src, &width),
50+
arg2: ArmVal::Imm(0),
51+
}
4852
},
4953
RiscVInstruction::Add {
5054
width,
@@ -87,7 +91,7 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
8791
}
8892

8993
ArmInstruction::Add {
90-
dest: map_register(dest),
94+
dest: map_register(dest, &RiscVWidth::Double),
9195
arg1: ArmRegister {
9296
width: ArmWidth::Double,
9397
name: ArmRegisterName::Zero,
@@ -98,68 +102,64 @@ pub fn translate(riscv_instr: RiscVInstruction) -> ArmInstruction {
98102
}
99103
}
100104

101-
fn map_register(riscv_reg: RiscVRegister) -> ArmRegister {
102-
match riscv_reg {
103-
RiscVRegister::X0 => todo!("Arm doesn't have a zero register"),
104-
// RiscVRegister::RA => ArmRegister::Lr,
105-
// RiscVRegister::SP => ArmRegister::Sp,
106-
// RiscVRegister::GP => ArmRegister::,
107-
// RiscVRegister::TP => ArmRegister::,
108-
// RiscVRegister::T0 => ArmRegister::,
109-
// RiscVRegister::T1 => ArmRegister::,
110-
// RiscVRegister::T2 => ArmRegister::,
111-
// RiscVRegister::S0FP => ArmRegister::,
112-
// RiscVRegister::S1 => ArmRegister::,
113-
// RiscVRegister::A0 => ArmRegister::,
114-
// RiscVRegister::A1 => ArmRegister::,
115-
// RiscVRegister::A2 => ArmRegister::,
116-
// RiscVRegister::A3 => ArmRegister::,
117-
// RiscVRegister::A4 => ArmRegister::,
118-
// RiscVRegister::A5 => ArmRegister::,
119-
// RiscVRegister::A6 => ArmRegister::,
120-
// RiscVRegister::A7 => ArmRegister::,
121-
// RiscVRegister::S2 => ArmRegister::,
122-
// RiscVRegister::S3 => ArmRegister::,
123-
// RiscVRegister::S4 => ArmRegister::,
124-
// RiscVRegister::S5 => ArmRegister::,
125-
// RiscVRegister::S6 => ArmRegister::,
126-
// RiscVRegister::S7 => ArmRegister::,
127-
// RiscVRegister::S8 => ArmRegister::,
128-
// RiscVRegister::S9 => ArmRegister::,
129-
// RiscVRegister::S10 => ArmRegister::,
130-
// RiscVRegister::S11 => ArmRegister::,
131-
// RiscVRegister::T3 => ArmRegister::,
132-
// RiscVRegister::T4 => ArmRegister::,
133-
// RiscVRegister::T5 => ArmRegister::,
134-
// RiscVRegister::T6 => ArmRegister::,
135-
// FIXME: do real implementation
136-
_ => ArmRegister {
137-
width: ArmWidth::Double,
138-
name: ArmRegisterName::Sp,
139-
},
105+
fn map_register(riscv_reg: RiscVRegister, riscv_width: &RiscVWidth) -> ArmRegister {
106+
ArmRegister {
107+
width: map_width(riscv_width),
108+
name: map_register_name(riscv_reg)
140109
}
141110
}
142111

112+
/// Semantic meaning of registers
113+
/// https://riscv.org/wp-content/uploads/2024/12/riscv-calling.pdf#page=3
143114
fn map_register_name(riscv_reg: RiscVRegister) -> ArmRegisterName {
144-
// todo!()
145-
// FIXME: do real implementation
146-
ArmRegisterName::A1
115+
match riscv_reg {
116+
RiscVRegister::X0 => ArmRegisterName::Zero,
117+
RiscVRegister::RA => ArmRegisterName::Lr,
118+
RiscVRegister::SP => ArmRegisterName::Sp,
119+
RiscVRegister::GP => ArmRegisterName::X0,
120+
RiscVRegister::TP => ArmRegisterName::X1,
121+
RiscVRegister::T0 => ArmRegisterName::X2,
122+
RiscVRegister::T1 => ArmRegisterName::X3,
123+
RiscVRegister::T2 => ArmRegisterName::X4,
124+
RiscVRegister::S0FP => ArmRegisterName::X5,
125+
RiscVRegister::S1 => ArmRegisterName::X6,
126+
RiscVRegister::A0 => ArmRegisterName::X7,
127+
RiscVRegister::A1 => ArmRegisterName::X8,
128+
RiscVRegister::A2 => ArmRegisterName::X9,
129+
RiscVRegister::A3 => ArmRegisterName::X10,
130+
RiscVRegister::A4 => ArmRegisterName::X11,
131+
RiscVRegister::A5 => ArmRegisterName::X12,
132+
RiscVRegister::A6 => ArmRegisterName::X13,
133+
RiscVRegister::A7 => ArmRegisterName::X14,
134+
RiscVRegister::S2 => ArmRegisterName::X15,
135+
RiscVRegister::S3 => ArmRegisterName::X16,
136+
RiscVRegister::S4 => ArmRegisterName::X17,
137+
RiscVRegister::S5 => ArmRegisterName::X18,
138+
RiscVRegister::S6 => ArmRegisterName::X19,
139+
RiscVRegister::S7 => ArmRegisterName::X20,
140+
RiscVRegister::S8 => ArmRegisterName::X21,
141+
RiscVRegister::S9 => ArmRegisterName::X22,
142+
RiscVRegister::S10 => ArmRegisterName::X23,
143+
RiscVRegister::S11 => ArmRegisterName::X24,
144+
RiscVRegister::T3 => ArmRegisterName::X25,
145+
RiscVRegister::T4 => ArmRegisterName::X26,
146+
RiscVRegister::T5 => ArmRegisterName::X27,
147+
RiscVRegister::T6 => ArmRegisterName::X28,
148+
}
147149
}
148150

149-
fn map_val(riscv_val: RiscVVal) -> ArmVal {
151+
fn map_val(riscv_val: RiscVVal, riscv_width: &RiscVWidth) -> ArmVal {
150152
match riscv_val {
151-
RiscVVal::RiscVRegister(riscv_reg) => ArmVal::Reg(map_register(riscv_reg)),
153+
RiscVVal::RiscVRegister(riscv_reg) => ArmVal::Reg(map_register(riscv_reg, riscv_width)),
152154
RiscVVal::Immediate(imm) => ArmVal::Imm(imm),
153-
RiscVVal::Offset { register, offset } => ArmVal::RegOffset(map_register(register), offset),
155+
RiscVVal::Offset { register, offset } => ArmVal::RegOffset(map_register(register, riscv_width), offset),
154156
}
155157
}
156158

157-
fn map_width(riscv_width: RiscVWidth) -> ArmWidth {
158-
match riscv_width {
159-
RiscVWidth::Word => ArmWidth::Word,
160-
RiscVWidth::Double => ArmWidth::Double,
161-
// todo!()
162-
}
159+
fn map_width(riscv_width: &RiscVWidth) -> ArmWidth {
160+
// todo!()
161+
// FIXME: do real implementation
162+
ArmWidth::Double
163163
}
164164

165165
// Translate every instruction 1:1

0 commit comments

Comments
 (0)