@@ -24,15 +24,13 @@ pub const EC: Opnd = Opnd::Reg(X20_REG);
2424pub const SP : Opnd = Opnd :: Reg ( X21_REG ) ;
2525
2626// C argument registers on this platform
27- pub const C_ARG_OPNDS : [ Opnd ; 8 ] = [
27+ pub const C_ARG_OPNDS : [ Opnd ; 6 ] = [
2828 Opnd :: Reg ( X0_REG ) ,
2929 Opnd :: Reg ( X1_REG ) ,
3030 Opnd :: Reg ( X2_REG ) ,
3131 Opnd :: Reg ( X3_REG ) ,
3232 Opnd :: Reg ( X4_REG ) ,
33- Opnd :: Reg ( X5_REG ) ,
34- Opnd :: Reg ( X6_REG ) ,
35- Opnd :: Reg ( X7_REG )
33+ Opnd :: Reg ( X5_REG )
3634] ;
3735
3836// C return value register on this platform
@@ -201,8 +199,6 @@ pub const ALLOC_REGS: &[Reg] = &[
201199 X3_REG ,
202200 X4_REG ,
203201 X5_REG ,
204- X6_REG ,
205- X7_REG ,
206202 X11_REG ,
207203 X12_REG ,
208204] ;
@@ -235,7 +231,7 @@ impl Assembler {
235231
236232 /// Get a list of all of the caller-saved registers
237233 pub fn get_caller_save_regs ( ) -> Vec < Reg > {
238- vec ! [ X1_REG , X6_REG , X7_REG , X9_REG , X10_REG , X11_REG , X12_REG , X13_REG , X14_REG , X15_REG ]
234+ vec ! [ X1_REG , X9_REG , X10_REG , X11_REG , X12_REG , X13_REG , X14_REG , X15_REG ]
239235 }
240236
241237 /// How many bytes a call and a [Self::frame_setup] would change native SP
@@ -492,13 +488,31 @@ impl Assembler {
492488 }
493489 */
494490 Insn :: CCall { opnds, .. } => {
495- opnds. iter_mut ( ) . for_each ( |opnd| {
496- * opnd = match opnd {
497- Opnd :: UImm ( 0 ) | Opnd :: Imm ( 0 ) => Opnd :: UImm ( 0 ) ,
498- Opnd :: Mem ( _) => split_memory_address ( asm, * opnd) ,
499- _ => * opnd
500- } ;
501- } ) ;
491+ assert ! ( opnds. len( ) <= C_ARG_OPNDS . len( ) ) ;
492+
493+ // Load each operand into the corresponding argument
494+ // register.
495+ // Note: the iteration order is reversed to avoid corrupting x0,
496+ // which is both the return value and first argument register
497+ if !opnds. is_empty ( ) {
498+ let mut args: Vec < ( Opnd , Opnd ) > = vec ! [ ] ;
499+ for ( idx, opnd) in opnds. iter_mut ( ) . enumerate ( ) . rev ( ) {
500+ // If the value that we're sending is 0, then we can use
501+ // the zero register, so in this case we'll just send
502+ // a UImm of 0 along as the argument to the move.
503+ let value = match opnd {
504+ Opnd :: UImm ( 0 ) | Opnd :: Imm ( 0 ) => Opnd :: UImm ( 0 ) ,
505+ Opnd :: Mem ( _) => split_memory_address ( asm, * opnd) ,
506+ _ => * opnd
507+ } ;
508+ args. push ( ( C_ARG_OPNDS [ idx] , value) ) ;
509+ }
510+ asm. parallel_mov ( args) ;
511+ }
512+
513+ // Now we push the CCall without any arguments so that it
514+ // just performs the call.
515+ * opnds = vec ! [ ] ;
502516 asm. push_insn ( insn) ;
503517 } ,
504518 Insn :: Cmp { left, right } => {
@@ -1843,19 +1857,17 @@ mod tests {
18431857
18441858 assert_disasm_snapshot ! ( cb. disasm( ) , @r"
18451859 0x0: str x1, [sp, #-0x10]!
1846- 0x4: str x6, [sp, #-0x10]!
1847- 0x8: str x7, [sp, #-0x10]!
1848- 0xc: str x9, [sp, #-0x10]!
1849- 0x10: str x10, [sp, #-0x10]!
1850- 0x14: str x11, [sp, #-0x10]!
1851- 0x18: str x12, [sp, #-0x10]!
1852- 0x1c: str x13, [sp, #-0x10]!
1853- 0x20: str x14, [sp, #-0x10]!
1854- 0x24: str x15, [sp, #-0x10]!
1855- 0x28: mrs x16, nzcv
1856- 0x2c: str x16, [sp, #-0x10]!
1860+ 0x4: str x9, [sp, #-0x10]!
1861+ 0x8: str x10, [sp, #-0x10]!
1862+ 0xc: str x11, [sp, #-0x10]!
1863+ 0x10: str x12, [sp, #-0x10]!
1864+ 0x14: str x13, [sp, #-0x10]!
1865+ 0x18: str x14, [sp, #-0x10]!
1866+ 0x1c: str x15, [sp, #-0x10]!
1867+ 0x20: mrs x16, nzcv
1868+ 0x24: str x16, [sp, #-0x10]!
18571869 " ) ;
1858- assert_snapshot ! ( cb. hexdump( ) , @"e10f1ff8e60f1ff8e70f1ff8e90f1ff8ea0f1ff8eb0f1ff8ec0f1ff8ed0f1ff8ee0f1ff8ef0f1ff810423bd5f00f1ff8 " ) ;
1870+ assert_snapshot ! ( cb. hexdump( ) , @"e10f1ff8e90f1ff8ea0f1ff8eb0f1ff8ec0f1ff8ed0f1ff8ee0f1ff8ef0f1ff810423bd5f00f1ff8 " ) ;
18591871 }
18601872
18611873 #[ test]
@@ -1875,11 +1887,9 @@ mod tests {
18751887 0x18: ldr x11, [sp], #0x10
18761888 0x1c: ldr x10, [sp], #0x10
18771889 0x20: ldr x9, [sp], #0x10
1878- 0x24: ldr x7, [sp], #0x10
1879- 0x28: ldr x6, [sp], #0x10
1880- 0x2c: ldr x1, [sp], #0x10
1890+ 0x24: ldr x1, [sp], #0x10
18811891 " ) ;
1882- assert_snapshot ! ( cb. hexdump( ) , @"10421bd5f00741f8ef0741f8ee0741f8ed0741f8ec0741f8eb0741f8ea0741f8e90741f8e70741f8e60741f8e10741f8 " ) ;
1892+ assert_snapshot ! ( cb. hexdump( ) , @"10421bd5f00741f8ef0741f8ee0741f8ed0741f8ec0741f8eb0741f8ea0741f8e90741f8e10741f8 " ) ;
18831893 }
18841894
18851895 #[ test]
@@ -2648,14 +2658,14 @@ mod tests {
26482658 ] ) ;
26492659 asm. compile_with_num_regs ( & mut cb, ALLOC_REGS . len ( ) ) ;
26502660
2651- assert_disasm_snapshot ! ( cb. disasm( ) , @r "
2652- 0x0: mov x15, x1
2653- 0x4: mov x1, x0
2654- 0x8: mov x0 , x15
2655- 0xc: mov x16, #0
2656- 0x10: blr x16
2661+ assert_disasm_snapshot ! ( cb. disasm( ) , @"
2662+ 0x0: mov x15, x0
2663+ 0x4: mov x0, x1
2664+ 0x8: mov x1 , x15
2665+ 0xc: mov x16, #0
2666+ 0x10: blr x16
26572667 " ) ;
2658- assert_snapshot ! ( cb. hexdump( ) , @"ef0301aae10300aae0030faa100080d200023fd6 " ) ;
2668+ assert_snapshot ! ( cb. hexdump( ) , @"ef0300aae00301aae1030faa100080d200023fd6 " ) ;
26592669 }
26602670
26612671 #[ test]
@@ -2671,17 +2681,17 @@ mod tests {
26712681 ] ) ;
26722682 asm. compile_with_num_regs ( & mut cb, ALLOC_REGS . len ( ) ) ;
26732683
2674- assert_disasm_snapshot ! ( cb. disasm( ) , @r "
2675- 0x0: mov x15, x1
2676- 0x4: mov x1, x0
2677- 0x8: mov x0 , x15
2678- 0xc: mov x15, x3
2679- 0x10: mov x3, x2
2680- 0x14: mov x2 , x15
2681- 0x18: mov x16, #0
2682- 0x1c: blr x16
2684+ assert_disasm_snapshot ! ( cb. disasm( ) , @"
2685+ 0x0: mov x15, x2
2686+ 0x4: mov x2, x3
2687+ 0x8: mov x3 , x15
2688+ 0xc: mov x15, x0
2689+ 0x10: mov x0, x1
2690+ 0x14: mov x1 , x15
2691+ 0x18: mov x16, #0
2692+ 0x1c: blr x16
26832693 " ) ;
2684- assert_snapshot ! ( cb. hexdump( ) , @"ef0301aae10300aae0030faaef0303aae30302aae2030faa100080d200023fd6 " ) ;
2694+ assert_snapshot ! ( cb. hexdump( ) , @"ef0302aae20303aae3030faaef0300aae00301aae1030faa100080d200023fd6 " ) ;
26852695 }
26862696
26872697 #[ test]
@@ -2696,15 +2706,15 @@ mod tests {
26962706 ] ) ;
26972707 asm. compile_with_num_regs ( & mut cb, ALLOC_REGS . len ( ) ) ;
26982708
2699- assert_disasm_snapshot ! ( cb. disasm( ) , @r "
2700- 0x0: mov x15, x1
2701- 0x4: mov x1, x2
2702- 0x8: mov x2, x0
2703- 0xc: mov x0 , x15
2704- 0x10: mov x16, #0
2705- 0x14: blr x16
2709+ assert_disasm_snapshot ! ( cb. disasm( ) , @"
2710+ 0x0: mov x15, x0
2711+ 0x4: mov x0, x1
2712+ 0x8: mov x1, x2
2713+ 0xc: mov x2 , x15
2714+ 0x10: mov x16, #0
2715+ 0x14: blr x16
27062716 " ) ;
2707- assert_snapshot ! ( cb. hexdump( ) , @"ef0301aae10302aae20300aae0030faa100080d200023fd6 " ) ;
2717+ assert_snapshot ! ( cb. hexdump( ) , @"ef0300aae00301aae10302aae2030faa100080d200023fd6 " ) ;
27082718 }
27092719
27102720 #[ test]
0 commit comments