@@ -13,16 +13,15 @@ use alloc::boxed::Box;
1313use alloc:: vec:: Vec ;
1414use regalloc:: { RealReg , Reg , RegClass , Set , Writable } ;
1515use smallvec:: SmallVec ;
16- use std:: convert:: TryFrom ;
1716
1817// We use a generic implementation that factors out AArch64 and x64 ABI commonalities, because
1918// these ABIs are very similar.
2019
2120/// Support for the AArch64 ABI from the callee side (within a function body).
22- pub type AArch64ABIBody = ABIBodyImpl < AArch64MachineImpl > ;
21+ pub ( crate ) type AArch64ABICallee = ABICalleeImpl < AArch64MachineDeps > ;
2322
2423/// Support for the AArch64 ABI from the caller side (at a callsite).
25- pub type AArch64ABICall = ABICallImpl < AArch64MachineImpl > ;
24+ pub ( crate ) type AArch64ABICaller = ABICallerImpl < AArch64MachineDeps > ;
2625
2726// Spidermonkey specific ABI convention.
2827
@@ -105,9 +104,9 @@ impl Into<AMode> for StackAMode {
105104
106105/// AArch64-specific ABI behavior. This struct just serves as an implementation
107106/// point for the trait; it is never actually instantiated.
108- pub struct AArch64MachineImpl ;
107+ pub ( crate ) struct AArch64MachineDeps ;
109108
110- impl ABIMachineImpl for AArch64MachineImpl {
109+ impl ABIMachineSpec for AArch64MachineDeps {
111110 type I = Inst ;
112111
113112 fn compute_arg_locs (
@@ -285,7 +284,8 @@ impl ABIMachineImpl for AArch64MachineImpl {
285284 Inst :: Ret
286285 }
287286
288- fn gen_add_imm ( into_reg : Writable < Reg > , from_reg : Reg , imm : u64 ) -> SmallVec < [ Inst ; 4 ] > {
287+ fn gen_add_imm ( into_reg : Writable < Reg > , from_reg : Reg , imm : u32 ) -> SmallVec < [ Inst ; 4 ] > {
288+ let imm = imm as u64 ;
289289 let mut insts = SmallVec :: new ( ) ;
290290 if let Some ( imm12) = Imm12 :: maybe_from_u64 ( imm) {
291291 insts. push ( Inst :: AluRRImm12 {
@@ -296,6 +296,7 @@ impl ABIMachineImpl for AArch64MachineImpl {
296296 } ) ;
297297 } else {
298298 let scratch2 = writable_tmp2_reg ( ) ;
299+ assert_ne ! ( scratch2. to_reg( ) , from_reg) ;
299300 insts. extend ( Inst :: load_constant ( scratch2, imm. into ( ) ) ) ;
300301 insts. push ( Inst :: AluRRRExtend {
301302 alu_op : ALUOp :: Add64 ,
@@ -334,29 +335,29 @@ impl ABIMachineImpl for AArch64MachineImpl {
334335 Inst :: LoadAddr { rd : into_reg, mem }
335336 }
336337
337- fn get_fixed_tmp_reg ( ) -> Reg {
338+ fn get_stacklimit_reg ( ) -> Reg {
338339 spilltmp_reg ( )
339340 }
340341
341- fn gen_load_base_offset ( into_reg : Writable < Reg > , base : Reg , offset : i64 , ty : Type ) -> Inst {
342- let mem = AMode :: RegOffset ( base, offset, ty) ;
342+ fn gen_load_base_offset ( into_reg : Writable < Reg > , base : Reg , offset : i32 , ty : Type ) -> Inst {
343+ let mem = AMode :: RegOffset ( base, offset as i64 , ty) ;
343344 Inst :: gen_load ( into_reg, mem, ty)
344345 }
345346
346- fn gen_store_base_offset ( base : Reg , offset : i64 , from_reg : Reg , ty : Type ) -> Inst {
347- let mem = AMode :: RegOffset ( base, offset, ty) ;
347+ fn gen_store_base_offset ( base : Reg , offset : i32 , from_reg : Reg , ty : Type ) -> Inst {
348+ let mem = AMode :: RegOffset ( base, offset as i64 , ty) ;
348349 Inst :: gen_store ( mem, from_reg, ty)
349350 }
350351
351- fn gen_sp_reg_adjust ( amount : i64 ) -> SmallVec < [ Inst ; 2 ] > {
352+ fn gen_sp_reg_adjust ( amount : i32 ) -> SmallVec < [ Inst ; 2 ] > {
352353 if amount == 0 {
353354 return SmallVec :: new ( ) ;
354355 }
355356
356357 let ( amount, is_sub) = if amount > 0 {
357- ( u64 :: try_from ( amount) . unwrap ( ) , false )
358+ ( amount as u64 , false )
358359 } else {
359- ( u64 :: try_from ( -amount) . unwrap ( ) , true )
360+ ( -amount as u64 , true )
360361 } ;
361362
362363 let alu_op = if is_sub { ALUOp :: Sub64 } else { ALUOp :: Add64 } ;
@@ -389,8 +390,10 @@ impl ABIMachineImpl for AArch64MachineImpl {
389390 ret
390391 }
391392
392- fn gen_nominal_sp_adj ( offset : i64 ) -> Inst {
393- Inst :: VirtualSPOffsetAdj { offset }
393+ fn gen_nominal_sp_adj ( offset : i32 ) -> Inst {
394+ Inst :: VirtualSPOffsetAdj {
395+ offset : offset as i64 ,
396+ }
394397 }
395398
396399 fn gen_prologue_frame_setup ( ) -> SmallVec < [ Inst ; 2 ] > {
@@ -553,11 +556,12 @@ impl ABIMachineImpl for AArch64MachineImpl {
553556 defs : Vec < Writable < Reg > > ,
554557 loc : SourceLoc ,
555558 opcode : ir:: Opcode ,
556- ) -> SmallVec < [ ( /* is_safepoint = */ bool , Inst ) ; 2 ] > {
559+ tmp : Writable < Reg > ,
560+ ) -> SmallVec < [ ( InstIsSafepoint , Inst ) ; 2 ] > {
557561 let mut insts = SmallVec :: new ( ) ;
558562 match & dest {
559563 & CallDest :: ExtName ( ref name, RelocDistance :: Near ) => insts. push ( (
560- true ,
564+ InstIsSafepoint :: Yes ,
561565 Inst :: Call {
562566 info : Box :: new ( CallInfo {
563567 dest : name. clone ( ) ,
@@ -570,19 +574,19 @@ impl ABIMachineImpl for AArch64MachineImpl {
570574 ) ) ,
571575 & CallDest :: ExtName ( ref name, RelocDistance :: Far ) => {
572576 insts. push ( (
573- false ,
577+ InstIsSafepoint :: No ,
574578 Inst :: LoadExtName {
575- rd : writable_spilltmp_reg ( ) ,
579+ rd : tmp ,
576580 name : Box :: new ( name. clone ( ) ) ,
577581 offset : 0 ,
578582 srcloc : loc,
579583 } ,
580584 ) ) ;
581585 insts. push ( (
582- true ,
586+ InstIsSafepoint :: Yes ,
583587 Inst :: CallInd {
584588 info : Box :: new ( CallIndInfo {
585- rn : spilltmp_reg ( ) ,
589+ rn : tmp . to_reg ( ) ,
586590 uses,
587591 defs,
588592 loc,
@@ -592,7 +596,7 @@ impl ABIMachineImpl for AArch64MachineImpl {
592596 ) ) ;
593597 }
594598 & CallDest :: Reg ( reg) => insts. push ( (
595- true ,
599+ InstIsSafepoint :: Yes ,
596600 Inst :: CallInd {
597601 info : Box :: new ( CallIndInfo {
598602 rn : * reg,
@@ -608,7 +612,7 @@ impl ABIMachineImpl for AArch64MachineImpl {
608612 insts
609613 }
610614
611- fn get_spillslot_size ( rc : RegClass , ty : Type ) -> u32 {
615+ fn get_number_of_spillslots_for_value ( rc : RegClass , ty : Type ) -> u32 {
612616 // We allocate in terms of 8-byte slots.
613617 match ( rc, ty) {
614618 ( RegClass :: I64 , _) => 1 ,
@@ -698,9 +702,10 @@ fn get_callee_saves(
698702 }
699703 }
700704 }
701- // Sort registers for deterministic code output.
702- int_saves. sort_by_key ( |r| r. to_reg ( ) . get_index ( ) ) ;
703- vec_saves. sort_by_key ( |r| r. to_reg ( ) . get_index ( ) ) ;
705+ // Sort registers for deterministic code output. We can do an unstable sort because the
706+ // registers will be unique (there are no dups).
707+ int_saves. sort_unstable_by_key ( |r| r. to_reg ( ) . get_index ( ) ) ;
708+ vec_saves. sort_unstable_by_key ( |r| r. to_reg ( ) . get_index ( ) ) ;
704709 ( int_saves, vec_saves)
705710}
706711
0 commit comments