@@ -67,11 +67,11 @@ impl From<Opnd> for A64Opnd {
6767 Opnd :: Mem ( Mem { base : MemBase :: Reg ( reg_no) , num_bits, disp } ) => {
6868 A64Opnd :: new_mem ( num_bits, A64Opnd :: Reg ( A64Reg { num_bits, reg_no } ) , disp)
6969 } ,
70- Opnd :: Mem ( Mem { base : MemBase :: InsnOut ( _) , .. } ) => {
71- panic ! ( "attempted to lower an Opnd::Mem with a MemBase::InsnOut base" )
70+ Opnd :: Mem ( Mem { base : MemBase :: VReg ( _) , .. } ) => {
71+ panic ! ( "attempted to lower an Opnd::Mem with a MemBase::VReg base" )
7272 } ,
7373 Opnd :: CArg ( _) => panic ! ( "attempted to lower an Opnd::CArg" ) ,
74- Opnd :: InsnOut { .. } => panic ! ( "attempted to lower an Opnd::InsnOut " ) ,
74+ Opnd :: VReg { .. } => panic ! ( "attempted to lower an Opnd::VReg " ) ,
7575 Opnd :: Param { .. } => panic ! ( "attempted to lower an Opnd::Param" ) ,
7676 Opnd :: Value ( _) => panic ! ( "attempted to lower an Opnd::Value" ) ,
7777 Opnd :: None => panic ! (
@@ -226,7 +226,7 @@ impl Assembler
226226 let disp = asm. load ( Opnd :: Imm ( disp. into ( ) ) ) ;
227227 let reg = match base {
228228 MemBase :: Reg ( reg_no) => Opnd :: Reg ( Reg { reg_no, num_bits } ) ,
229- MemBase :: InsnOut ( idx) => Opnd :: InsnOut { idx, num_bits }
229+ MemBase :: VReg ( idx) => Opnd :: VReg { idx, num_bits }
230230 } ;
231231
232232 asm. add ( reg, disp)
@@ -258,7 +258,7 @@ impl Assembler
258258 /// to be split in case their displacement doesn't fit into 9 bits.
259259 fn split_load_operand ( asm : & mut Assembler , opnd : Opnd ) -> Opnd {
260260 match opnd {
261- Opnd :: Reg ( _) | Opnd :: InsnOut { .. } => opnd,
261+ Opnd :: Reg ( _) | Opnd :: VReg { .. } => opnd,
262262 Opnd :: Mem ( _) => {
263263 let split_opnd = split_memory_address ( asm, opnd) ;
264264 let out_opnd = asm. load ( split_opnd) ;
@@ -279,7 +279,7 @@ impl Assembler
279279 /// do follow that encoding, and if they don't then we load them first.
280280 fn split_bitmask_immediate ( asm : & mut Assembler , opnd : Opnd , dest_num_bits : u8 ) -> Opnd {
281281 match opnd {
282- Opnd :: Reg ( _) | Opnd :: CArg ( _) | Opnd :: InsnOut { .. } | Opnd :: Param { .. } => opnd,
282+ Opnd :: Reg ( _) | Opnd :: CArg ( _) | Opnd :: VReg { .. } | Opnd :: Param { .. } => opnd,
283283 Opnd :: Mem ( _) => split_load_operand ( asm, opnd) ,
284284 Opnd :: Imm ( imm) => {
285285 if imm == 0 {
@@ -312,7 +312,7 @@ impl Assembler
312312 /// a certain size. If they don't then we need to load them first.
313313 fn split_shifted_immediate ( asm : & mut Assembler , opnd : Opnd ) -> Opnd {
314314 match opnd {
315- Opnd :: Reg ( _) | Opnd :: CArg ( _) | Opnd :: InsnOut { .. } | Opnd :: Param { .. } => opnd,
315+ Opnd :: Reg ( _) | Opnd :: CArg ( _) | Opnd :: VReg { .. } | Opnd :: Param { .. } => opnd,
316316 Opnd :: Mem ( _) => split_load_operand ( asm, opnd) ,
317317 Opnd :: Imm ( imm) => if ShiftedImmediate :: try_from ( imm as u64 ) . is_ok ( ) {
318318 opnd
@@ -353,12 +353,12 @@ impl Assembler
353353 /// Returns the operands that should be used for a csel instruction.
354354 fn split_csel_operands ( asm : & mut Assembler , opnd0 : Opnd , opnd1 : Opnd ) -> ( Opnd , Opnd ) {
355355 let opnd0 = match opnd0 {
356- Opnd :: Reg ( _) | Opnd :: InsnOut { .. } => opnd0,
356+ Opnd :: Reg ( _) | Opnd :: VReg { .. } => opnd0,
357357 _ => split_load_operand ( asm, opnd0)
358358 } ;
359359
360360 let opnd1 = match opnd1 {
361- Opnd :: Reg ( _) | Opnd :: InsnOut { .. } => opnd1,
361+ Opnd :: Reg ( _) | Opnd :: VReg { .. } => opnd1,
362362 _ => split_load_operand ( asm, opnd1)
363363 } ;
364364
@@ -367,7 +367,7 @@ impl Assembler
367367
368368 fn split_less_than_32_cmp ( asm : & mut Assembler , opnd0 : Opnd ) -> Opnd {
369369 match opnd0 {
370- Opnd :: Reg ( _) | Opnd :: InsnOut { .. } => {
370+ Opnd :: Reg ( _) | Opnd :: VReg { .. } => {
371371 match opnd0. rm_num_bits ( ) {
372372 8 => asm. and ( opnd0. with_num_bits ( 64 ) . unwrap ( ) , Opnd :: UImm ( 0xff ) ) ,
373373 16 => asm. and ( opnd0. with_num_bits ( 64 ) . unwrap ( ) , Opnd :: UImm ( 0xffff ) ) ,
@@ -379,12 +379,12 @@ impl Assembler
379379 }
380380 }
381381
382- let live_ranges: Vec < usize > = take ( & mut self . live_ranges ) ;
383- let mut asm_local = Assembler :: new_with_label_names ( take ( & mut self . label_names ) ) ;
382+ let live_ranges: Vec < LiveRange > = take ( & mut self . live_ranges ) ;
383+ let mut iterator = self . insns . into_iter ( ) . enumerate ( ) . peekable ( ) ;
384+ let mut asm_local = Assembler :: new_with_label_names ( take ( & mut self . label_names ) , live_ranges. len ( ) ) ;
384385 let asm = & mut asm_local;
385- let mut iterator = self . into_draining_iter ( ) ;
386386
387- while let Some ( ( index, mut insn) ) = iterator. next_mapped ( ) {
387+ while let Some ( ( index, mut insn) ) = iterator. next ( ) {
388388 // Here we're going to map the operands of the instruction to load
389389 // any Opnd::Value operands into registers if they are heap objects
390390 // such that only the Op::Load instruction needs to handle that
@@ -415,18 +415,19 @@ impl Assembler
415415 match & mut insn {
416416 Insn :: Add { left, right, .. } => {
417417 match ( * left, * right) {
418- ( Opnd :: Reg ( _) | Opnd :: InsnOut { .. } , Opnd :: Reg ( _) | Opnd :: InsnOut { .. } ) => {
419- asm. add ( * left , * right ) ;
418+ ( Opnd :: Reg ( _) | Opnd :: VReg { .. } , Opnd :: Reg ( _) | Opnd :: VReg { .. } ) => {
419+ asm. push_insn ( insn ) ;
420420 } ,
421- ( reg_opnd @ ( Opnd :: Reg ( _) | Opnd :: InsnOut { .. } ) , other_opnd) |
422- ( other_opnd, reg_opnd @ ( Opnd :: Reg ( _) | Opnd :: InsnOut { .. } ) ) => {
423- let opnd1 = split_shifted_immediate ( asm, other_opnd) ;
424- asm. add ( reg_opnd, opnd1) ;
421+ ( reg_opnd @ ( Opnd :: Reg ( _) | Opnd :: VReg { .. } ) , other_opnd) |
422+ ( other_opnd, reg_opnd @ ( Opnd :: Reg ( _) | Opnd :: VReg { .. } ) ) => {
423+ * left = reg_opnd;
424+ * right = split_shifted_immediate ( asm, other_opnd) ;
425+ asm. push_insn ( insn) ;
425426 } ,
426427 _ => {
427- let opnd0 = split_load_operand ( asm, * left) ;
428- let opnd1 = split_shifted_immediate ( asm, * right) ;
429- asm. add ( opnd0 , opnd1 ) ;
428+ * left = split_load_operand ( asm, * left) ;
429+ * right = split_shifted_immediate ( asm, * right) ;
430+ asm. push_insn ( insn ) ;
430431 }
431432 }
432433 } ,
@@ -441,19 +442,11 @@ impl Assembler
441442 // registers and an output register, look to merge with an `Insn::Mov` that
442443 // follows which puts the output in another register. For example:
443444 // `Add a, b => out` followed by `Mov c, out` becomes `Add a, b => c`.
444- if let ( Opnd :: Reg ( _) , Opnd :: Reg ( _) , Some ( Insn :: Mov { dest, src } ) ) = ( left, right, iterator. peek ( ) ) {
445- if live_ranges[ index] == index + 1 {
446- // Check after potentially lowering a stack operand to a register operand
447- //let lowered_dest = if let Opnd::Stack { .. } = dest {
448- // asm.lower_stack_opnd(dest)
449- //} else {
450- // *dest
451- //};
452- let lowered_dest = * dest;
453- if out == src && matches ! ( lowered_dest, Opnd :: Reg ( _) ) {
454- * out = lowered_dest;
455- iterator. map_insn_index ( asm) ;
456- iterator. next_unmapped ( ) ; // Pop merged Insn::Mov
445+ if let ( Opnd :: Reg ( _) , Opnd :: Reg ( _) , Some ( Insn :: Mov { dest, src } ) ) = ( left, right, iterator. peek ( ) . map ( |( _, insn) | insn) ) {
446+ if live_ranges[ out. vreg_idx ( ) ] . end ( ) == index + 1 {
447+ if out == src && matches ! ( * dest, Opnd :: Reg ( _) ) {
448+ * out = * dest;
449+ iterator. next ( ) ; // Pop merged Insn::Mov
457450 }
458451 }
459452 }
@@ -489,7 +482,7 @@ impl Assembler
489482 iterator.next_unmapped(); // Pop merged jump instruction
490483 }
491484 */
492- Insn :: CCall { opnds, fptr , .. } => {
485+ Insn :: CCall { opnds, .. } => {
493486 assert ! ( opnds. len( ) <= C_ARG_OPNDS . len( ) ) ;
494487
495488 // Load each operand into the corresponding argument
@@ -511,14 +504,15 @@ impl Assembler
511504
512505 // Now we push the CCall without any arguments so that it
513506 // just performs the call.
514- asm. ccall ( * fptr, vec ! [ ] ) ;
507+ * opnds = vec ! [ ] ;
508+ asm. push_insn ( insn) ;
515509 } ,
516510 Insn :: Cmp { left, right } => {
517511 let opnd0 = split_load_operand ( asm, * left) ;
518512 let opnd0 = split_less_than_32_cmp ( asm, opnd0) ;
519513 let split_right = split_shifted_immediate ( asm, * right) ;
520514 let opnd1 = match split_right {
521- Opnd :: InsnOut { .. } if opnd0. num_bits ( ) != split_right. num_bits ( ) => {
515+ Opnd :: VReg { .. } if opnd0. num_bits ( ) != split_right. num_bits ( ) => {
522516 split_right. with_num_bits ( opnd0. num_bits ( ) . unwrap ( ) ) . unwrap ( )
523517 } ,
524518 _ => split_right
@@ -560,13 +554,12 @@ impl Assembler
560554 * truthy = opnd0;
561555 * falsy = opnd1;
562556 // Merge `csel` and `mov` into a single `csel` when possible
563- match iterator. peek ( ) {
557+ match iterator. peek ( ) . map ( | ( _ , insn ) | insn ) {
564558 Some ( Insn :: Mov { dest : Opnd :: Reg ( reg) , src } )
565- if matches ! ( out, Opnd :: InsnOut { .. } ) && * out == * src && live_ranges[ index ] == index + 1 => {
559+ if matches ! ( out, Opnd :: VReg { .. } ) && * out == * src && live_ranges[ out . vreg_idx ( ) ] . end ( ) == index + 1 => {
566560 * out = Opnd :: Reg ( * reg) ;
567561 asm. push_insn ( insn) ;
568- iterator. map_insn_index ( asm) ;
569- iterator. next_unmapped ( ) ; // Pop merged Insn::Mov
562+ iterator. next ( ) ; // Pop merged Insn::Mov
570563 }
571564 _ => {
572565 asm. push_insn ( insn) ;
@@ -597,19 +590,19 @@ impl Assembler
597590 } ;
598591 asm. push_insn ( insn) ;
599592 } ,
600- Insn :: LoadSExt { opnd, .. } => {
593+ Insn :: LoadSExt { opnd, out } => {
601594 match opnd {
602595 // We only want to sign extend if the operand is a
603596 // register, instruction output, or memory address that
604597 // is 32 bits. Otherwise we'll just load the value
605598 // directly since there's no need to sign extend.
606599 Opnd :: Reg ( Reg { num_bits : 32 , .. } ) |
607- Opnd :: InsnOut { num_bits : 32 , .. } |
600+ Opnd :: VReg { num_bits : 32 , .. } |
608601 Opnd :: Mem ( Mem { num_bits : 32 , .. } ) => {
609- asm. load_sext ( * opnd ) ;
602+ asm. push_insn ( insn ) ;
610603 } ,
611604 _ => {
612- asm. load ( * opnd) ;
605+ asm. push_insn ( Insn :: Load { opnd : * opnd, out : * out } ) ;
613606 }
614607 } ;
615608 } ,
@@ -657,12 +650,11 @@ impl Assembler
657650 Insn :: Not { opnd, .. } => {
658651 // The value that is being negated must be in a register, so
659652 // if we get anything else we need to load it first.
660- let opnd0 = match opnd {
653+ * opnd = match opnd {
661654 Opnd :: Mem ( _) => split_load_operand ( asm, * opnd) ,
662655 _ => * opnd
663656 } ;
664-
665- asm. not ( opnd0) ;
657+ asm. push_insn ( insn) ;
666658 } ,
667659 Insn :: LShift { opnd, .. } |
668660 Insn :: RShift { opnd, .. } |
@@ -703,14 +695,14 @@ impl Assembler
703695 }
704696 } ,
705697 Insn :: Sub { left, right, .. } => {
706- let opnd0 = split_load_operand ( asm, * left) ;
707- let opnd1 = split_shifted_immediate ( asm, * right) ;
708- asm. sub ( opnd0 , opnd1 ) ;
698+ * left = split_load_operand ( asm, * left) ;
699+ * right = split_shifted_immediate ( asm, * right) ;
700+ asm. push_insn ( insn ) ;
709701 } ,
710702 Insn :: Mul { left, right, .. } => {
711- let opnd0 = split_load_operand ( asm, * left) ;
712- let opnd1 = split_load_operand ( asm, * right) ;
713- asm. mul ( opnd0 , opnd1 ) ;
703+ * left = split_load_operand ( asm, * left) ;
704+ * right = split_load_operand ( asm, * right) ;
705+ asm. push_insn ( insn ) ;
714706 } ,
715707 Insn :: Test { left, right } => {
716708 // The value being tested must be in a register, so if it's
@@ -725,19 +717,9 @@ impl Assembler
725717 asm. test ( opnd0, opnd1) ;
726718 } ,
727719 _ => {
728- // If we have an output operand, then we need to replace it
729- // with a new output operand from the new assembler.
730- if insn. out_opnd ( ) . is_some ( ) {
731- let out_num_bits = Opnd :: match_num_bits_iter ( insn. opnd_iter ( ) ) ;
732- let out = insn. out_opnd_mut ( ) . unwrap ( ) ;
733- * out = asm. next_opnd_out ( out_num_bits) ;
734- }
735-
736720 asm. push_insn ( insn) ;
737721 }
738- } ;
739-
740- iterator. map_insn_index ( asm) ;
722+ }
741723 }
742724
743725 asm_local
@@ -1015,7 +997,7 @@ impl Assembler
1015997 Insn :: Load { opnd, out } |
1016998 Insn :: LoadInto { opnd, dest : out } => {
1017999 match * opnd {
1018- Opnd :: Reg ( _) | Opnd :: InsnOut { .. } => {
1000+ Opnd :: Reg ( _) | Opnd :: VReg { .. } => {
10191001 mov ( cb, out. into ( ) , opnd. into ( ) ) ;
10201002 } ,
10211003 Opnd :: UImm ( uimm) => {
@@ -1063,7 +1045,7 @@ impl Assembler
10631045 Insn :: LoadSExt { opnd, out } => {
10641046 match * opnd {
10651047 Opnd :: Reg ( Reg { num_bits : 32 , .. } ) |
1066- Opnd :: InsnOut { num_bits : 32 , .. } => {
1048+ Opnd :: VReg { num_bits : 32 , .. } => {
10671049 sxtw ( cb, out. into ( ) , opnd. into ( ) ) ;
10681050 } ,
10691051 Opnd :: Mem ( Mem { num_bits : 32 , .. } ) => {
0 commit comments