@@ -14,7 +14,7 @@ use mov::Mov;
1414use crate :: asm:: { CodeBlock , imm_num_bits} ;
1515use super :: opnd:: * ;
1616
17- /// ADD
17+ /// ADD - add rn and rm, put the result in rd, don't update flags
1818pub fn add ( cb : & mut CodeBlock , rd : A64Opnd , rn : A64Opnd , rm : A64Opnd ) {
1919 let bytes: [ u8 ; 4 ] = match ( rd, rn, rm) {
2020 ( A64Opnd :: Reg ( rd) , A64Opnd :: Reg ( rn) , A64Opnd :: Reg ( rm) ) => {
@@ -37,7 +37,7 @@ pub fn add(cb: &mut CodeBlock, rd: A64Opnd, rn: A64Opnd, rm: A64Opnd) {
3737 cb. write_bytes ( & bytes) ;
3838}
3939
40- /// ADDS
40+ /// ADDS - add rn and rm, put the result in rd, update flags
4141pub fn adds ( cb : & mut CodeBlock , rd : A64Opnd , rn : A64Opnd , rm : A64Opnd ) {
4242 let bytes: [ u8 ; 4 ] = match ( rd, rn, rm) {
4343 ( A64Opnd :: Reg ( rd) , A64Opnd :: Reg ( rn) , A64Opnd :: Reg ( rm) ) => {
@@ -60,7 +60,17 @@ pub fn adds(cb: &mut CodeBlock, rd: A64Opnd, rn: A64Opnd, rm: A64Opnd) {
6060 cb. write_bytes ( & bytes) ;
6161}
6262
63- /// LDUR
63+ /// BR - branch to a register
64+ pub fn br ( cb : & mut CodeBlock , rn : A64Opnd ) {
65+ let bytes: [ u8 ; 4 ] = match rn {
66+ A64Opnd :: Reg ( rn) => Branch :: br ( rn. reg_no ) . into ( ) ,
67+ _ => panic ! ( "Invalid operand to br instruction." ) ,
68+ } ;
69+
70+ cb. write_bytes ( & bytes) ;
71+ }
72+
73+ /// LDUR - load a memory address into a register
6474pub fn ldur ( cb : & mut CodeBlock , rt : A64Opnd , rn : A64Opnd ) {
6575 let bytes: [ u8 ; 4 ] = match ( rt, rn) {
6676 ( A64Opnd :: Reg ( rt) , A64Opnd :: Mem ( rn) ) => {
@@ -75,7 +85,7 @@ pub fn ldur(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) {
7585 cb. write_bytes ( & bytes) ;
7686}
7787
78- /// MOVK
88+ /// MOVK - move a 16 bit immediate into a register, keep the other bits in place
7989pub fn movk ( cb : & mut CodeBlock , rd : A64Opnd , imm16 : A64Opnd , shift : u8 ) {
8090 let bytes: [ u8 ; 4 ] = match ( rd, imm16) {
8191 ( A64Opnd :: Reg ( rd) , A64Opnd :: UImm ( imm16) ) => {
@@ -89,7 +99,7 @@ pub fn movk(cb: &mut CodeBlock, rd: A64Opnd, imm16: A64Opnd, shift: u8) {
8999 cb. write_bytes ( & bytes) ;
90100}
91101
92- /// MOVZ
102+ /// MOVZ - move a 16 bit immediate into a register, zero the other bits
93103pub fn movz ( cb : & mut CodeBlock , rd : A64Opnd , imm16 : A64Opnd , shift : u8 ) {
94104 let bytes: [ u8 ; 4 ] = match ( rd, imm16) {
95105 ( A64Opnd :: Reg ( rd) , A64Opnd :: UImm ( imm16) ) => {
@@ -103,7 +113,7 @@ pub fn movz(cb: &mut CodeBlock, rd: A64Opnd, imm16: A64Opnd, shift: u8) {
103113 cb. write_bytes ( & bytes) ;
104114}
105115
106- /// SUB
116+ /// SUB - subtract rm from rn, put the result in rd, don't update flags
107117pub fn sub ( cb : & mut CodeBlock , rd : A64Opnd , rn : A64Opnd , rm : A64Opnd ) {
108118 let bytes: [ u8 ; 4 ] = match ( rd, rn, rm) {
109119 ( A64Opnd :: Reg ( rd) , A64Opnd :: Reg ( rn) , A64Opnd :: Reg ( rm) ) => {
@@ -126,7 +136,7 @@ pub fn sub(cb: &mut CodeBlock, rd: A64Opnd, rn: A64Opnd, rm: A64Opnd) {
126136 cb. write_bytes ( & bytes) ;
127137}
128138
129- /// SUBS
139+ /// SUBS - subtract rm from rn, put the result in rd, update flags
130140pub fn subs ( cb : & mut CodeBlock , rd : A64Opnd , rn : A64Opnd , rm : A64Opnd ) {
131141 let bytes: [ u8 ; 4 ] = match ( rd, rn, rm) {
132142 ( A64Opnd :: Reg ( rd) , A64Opnd :: Reg ( rn) , A64Opnd :: Reg ( rm) ) => {
@@ -149,12 +159,12 @@ pub fn subs(cb: &mut CodeBlock, rd: A64Opnd, rn: A64Opnd, rm: A64Opnd) {
149159 cb. write_bytes ( & bytes) ;
150160}
151161
152- /// RET
162+ /// RET - unconditionally return to a location in a register, defaults to X30
153163pub fn ret ( cb : & mut CodeBlock , rn : A64Opnd ) {
154164 let bytes: [ u8 ; 4 ] = match rn {
155165 A64Opnd :: None => Branch :: ret ( 30 ) . into ( ) ,
156166 A64Opnd :: Reg ( reg) => Branch :: ret ( reg. reg_no ) . into ( ) ,
157- _ => panic ! ( "Invalid operand for RET " )
167+ _ => panic ! ( "Invalid operand to ret instruction. " )
158168 } ;
159169
160170 cb. write_bytes ( & bytes) ;
@@ -191,6 +201,11 @@ mod tests {
191201 check_bytes ( "201c00b1" , |cb| adds ( cb, X0 , X1 , A64Opnd :: new_uimm ( 7 ) ) ) ;
192202 }
193203
204+ #[ test]
205+ fn test_br ( ) {
206+ check_bytes ( "80021fd6" , |cb| br ( cb, X20 ) ) ;
207+ }
208+
194209 #[ test]
195210 fn test_ldur ( ) {
196211 check_bytes ( "20b047f8" , |cb| ldur ( cb, X0 , A64Opnd :: new_mem ( X1 , 123 ) ) ) ;
0 commit comments