11use std:: convert:: Into ;
22use 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
131155impl 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
228272impl 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}
0 commit comments