Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 99 additions & 1 deletion src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,50 @@ pub enum RiscVInstruction {
arg1: RiscVRegister,
arg2: RiscVRegister,
},
#[strum(serialize = "subw")]
Sub {
// dest = arg1 - arg2
width: RiscVWidth,
dest: RiscVRegister,
arg1: RiscVRegister,
arg2: RiscVRegister,
},
/// branch if less than or equal
#[strum(serialize = "call")]
#[strum(serialize = "ble")]
Ble {
arg1: RiscVRegister,
arg2: RiscVRegister,
target: RiscVVal,
},
/// branch if greater than or equal
#[strum(serialize = "bge")]
Bge {
arg1: RiscVRegister,
arg2: RiscVRegister,
target: RiscVVal,
},
/// branch if less than
#[strum(serialize = "blt")]
Blt {
arg1: RiscVRegister,
arg2: RiscVRegister,
target: RiscVVal,
},
/// branch if greater than
#[strum(serialize = "bgt")]
Bgt {
arg1: RiscVRegister,
arg2: RiscVRegister,
target: RiscVVal,
},
/// branch if greater than
#[strum(serialize = "bne")]
Bne {
arg1: RiscVRegister,
arg2: RiscVRegister,
target: RiscVVal,
},
/// branch if greater than or equal to
/// call label
#[strum(serialize = "call")]
Call {
Expand All @@ -91,6 +128,13 @@ pub enum RiscVInstruction {
src: RiscVRegister,
dest: RiscVVal,
},
/// Rd := Rs << Imm
#[strum(serialize = "Slli")]
Slli {
dest: RiscVRegister,
src: RiscVRegister,
imm: i32
},
/// Loads a value from memory into register rd for RV64I.
///
/// `x[rd] = M[x[rs1] + sext(offset)]`
Expand Down Expand Up @@ -268,6 +312,34 @@ pub enum ArmInstruction {
arg2: ArmRegister,
target: ArmVal,
},
/// BGE label
#[strum(serialize = "bge")]
Bge {
arg1: ArmRegister,
arg2: ArmRegister,
target: ArmVal,
},
/// BLT label
#[strum(serialize = "blt")]
Blt {
arg1: ArmRegister,
arg2: ArmRegister,
target: ArmVal,
},
/// BGT label
#[strum(serialize = "bgt")]
Bgt {
arg1: ArmRegister,
arg2: ArmRegister,
target: ArmVal,
},
/// BNE label
#[strum(serialize = "bne")]
Bne {
arg1: ArmRegister,
arg2: ArmRegister,
target: ArmVal,
},
/// BL label
#[strum(serialize = "bl")]
Bl {
Expand Down Expand Up @@ -296,6 +368,13 @@ pub enum ArmInstruction {
},
#[strum(serialize = "ret")]
Ret,
/// Rd := Rs << Imm
#[strum(serialize = "Lsl")]
Lsl {
dest: ArmRegister,
src: ArmRegister,
imm: i32
},
/// Str [r2 + offset] = r1
#[strum(serialize = "str")]
Str {
Expand Down Expand Up @@ -579,9 +658,25 @@ impl Into<String> for ArmInstruction {
ArmInstruction::B { target } => {
format!("b {}", target)
}
// TODO: Fix these branching instructions need to map to
// multiple instructions. Would be better separation of concerns
// if this was produced by the translation function instead of a
// hack in the string formatting.
ArmInstruction::Ble { arg1, arg2, target } => {
format!("cmp {}, {}\nble {}", arg1, arg2, target)
}
ArmInstruction::Bge { arg1, arg2, target } => {
format!("cmp {}, {}\nbge {}", arg1, arg2, target)
}
ArmInstruction::Blt { arg1, arg2, target } => {
format!("cmp {}, {}\nblt {}", arg1, arg2, target)
}
ArmInstruction::Bgt { arg1, arg2, target } => {
format!("cmp {}, {}\nbgt {}", arg1, arg2, target)
}
ArmInstruction::Bne { arg1, arg2, target } => {
format!("cmp {}, {}\nbne {}", arg1, arg2, target)
}
ArmInstruction::Blr { target } => {
format!("blr {}", Into::<ArmRegister>::into(target))
}
Expand All @@ -598,6 +693,9 @@ impl Into<String> for ArmInstruction {
ArmWidth::Double => format!("str {}, {}", src, dest),
_ => todo!("{:?}", width),
},
ArmInstruction::Lsl { dest, src, imm } => {
format!("lsl {}, {}, {}", dest, src, imm)
}
ArmInstruction::Sub { dest, arg1, arg2 } => {
format!("sub {}, {}, {}", dest, arg1, arg2)
}
Expand Down
90 changes: 89 additions & 1 deletion src/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,38 @@ pub fn translate(riscv_instr: RiscVInstruction) -> Vec<ArmInstruction> {
target: map_val(target, &width),
}
}],
RiscVInstruction::Bge { arg1, arg2, target } => vec![{
let width = RiscVWidth::Double;
ArmInstruction::Bge {
arg1: map_register(arg1, &width),
arg2: map_register(arg2, &width),
target: map_val(target, &width),
}
}],
RiscVInstruction::Blt { arg1, arg2, target } => vec![{
let width = RiscVWidth::Double;
ArmInstruction::Blt {
arg1: map_register(arg1, &width),
arg2: map_register(arg2, &width),
target: map_val(target, &width),
}
}],
RiscVInstruction::Bgt { arg1, arg2, target } => vec![{
let width = RiscVWidth::Double;
ArmInstruction::Bgt {
arg1: map_register(arg1, &width),
arg2: map_register(arg2, &width),
target: map_val(target, &width),
}
}],
RiscVInstruction::Bne { arg1, arg2, target } => vec![{
let width = RiscVWidth::Double;
ArmInstruction::Bne {
arg1: map_register(arg1, &width),
arg2: map_register(arg2, &width),
target: map_val(target, &width),
}
}],
RiscVInstruction::J { target } => vec![ArmInstruction::B {
target: map_val(target, &RiscVWidth::Double),
}],
Expand All @@ -52,6 +84,14 @@ pub fn translate(riscv_instr: RiscVInstruction) -> Vec<ArmInstruction> {
src: map_register(src, &width),
dest: map_val(dest, &width),
}],
RiscVInstruction::Slli { dest, src, imm } => {
let width = RiscVWidth::Double;
vec![ArmInstruction::Lsl {
dest: map_register(dest, &width),
src: map_register(src, &width),
imm: imm
}]
},
RiscVInstruction::L { width, dest, src } => vec![ArmInstruction::Ldr {
width: map_width(&width),
dest: map_register(dest, &width),
Expand Down Expand Up @@ -101,7 +141,55 @@ pub fn translate(riscv_instr: RiscVInstruction) -> Vec<ArmInstruction> {
name: map_register_name(arg2),
}),
}],
RiscVWidth::Double => sorry!(),
RiscVWidth::Double => vec![ArmInstruction::Add {
dest: ArmRegister {
width: ArmWidth::Double,
name: map_register_name(dest),
},
arg1: ArmRegister {
width: ArmWidth::Double,
name: map_register_name(arg1),
},
arg2: ArmVal::Reg(ArmRegister {
width: ArmWidth::Double,
name: map_register_name(arg2),
}),
}],
},
RiscVInstruction::Sub {
width,
dest,
arg1,
arg2,
} => match width {
RiscVWidth::Word => vec![ArmInstruction::Sub {
dest: ArmRegister {
width: ArmWidth::Word,
name: map_register_name(dest),
},
arg1: ArmRegister {
width: ArmWidth::Word,
name: map_register_name(arg1),
},
arg2: ArmVal::Reg(ArmRegister {
width: ArmWidth::Word,
name: map_register_name(arg2),
}),
}],
RiscVWidth::Double => vec![ArmInstruction::Sub {
dest: ArmRegister {
width: ArmWidth::Double,
name: map_register_name(dest),
},
arg1: ArmRegister {
width: ArmWidth::Double,
name: map_register_name(arg1),
},
arg2: ArmVal::Reg(ArmRegister {
width: ArmWidth::Double,
name: map_register_name(arg2),
}),
}],
},
RiscVInstruction::SextW { dest, src } => vec![ArmInstruction::Sxtw {
dest: ArmRegister {
Expand Down
21 changes: 21 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ _main:
main:
"#;

pub const START_NO_MAIN: &str = r#"
.text

.global _start
.global _main

.balign 4
_start:
bl main
mov x8, #93
svc #0
"#;

/// Assembler directives for main only, used when another
/// function defined before main
pub const START_MAIN: &str = r#"
.balign 4
_main:
main:
"#;

pub fn translate_to_file(instrs: Vec<RiscVInstruction>, path: String) {
let arm_instrs = translate_instrs(instrs);
let mut contents = String::new();
Expand Down
65 changes: 65 additions & 0 deletions tests/fib/fib.arm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

.text

.global _start
.global _main

.balign 4
_start:
bl main
mov x8, #93
svc #0

.balign 4
_main:
main:

sub sp, sp, 64
str x29, [sp, 56]
add x29, sp, 64
str xzr, [x29, -64]
str xzr, [x29, -56]
str xzr, [x29, -48]
str xzr, [x29, -40]
str xzr, [x29, -32]
mov x5, 1
str w5, [x29, -60]
mov x5, 2
str w5, [x29, -20]
b .L2
.L3:
ldr w5, [x29, -20]
sub x5, x5, 1
sxtw x5, w5
lsl x5, x5, 2
sub x5, x5, 16
add x5, x5, x29
ldr x4, [x5, -48]
ldr x5, [x29, -20]
sub x5, x5, 2
sxtw x5, w5
lsl x5, x5, 2
sub x5, x5, 16
add x5, x5, x29
ldr x5, [x5, -48]
add x5, x4, x5
sxtw x4, w5
ldr x5, [x29, -20]
lsl x5, x5, 2
sub x5, x5, 16
add x5, x5, x29
str x4, [x5, -48]
ldr x5, [x29, -20]
add x5, x5, 1
str w5, [x29, -20]
.L2:
ldr x5, [x29, -20]
sxtw x4, w5
mov x5, 9
cmp x4, x5
ble .L3
ldr w5, [x29, -28]
add x0, x5, 0
ldr x29, [sp, 56]
add sp, sp, 64
blr lr
Loading