@@ -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 {
216243pub 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
0 commit comments