@@ -729,3 +729,83 @@ fn call_inline_asm<'tcx>(
729729 place. write_cvalue ( fx, CValue :: by_val ( value, place. layout ( ) ) ) ;
730730 }
731731}
732+
733+ pub ( crate ) fn codegen_xgetbv < ' tcx > (
734+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
735+ xcr_no : Value ,
736+ ret : CPlace < ' tcx > ,
737+ ) {
738+ // FIXME add .eh_frame unwind info directives
739+
740+ let operands = vec ! [
741+ CInlineAsmOperand :: In {
742+ reg: InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) ) ,
743+ value: xcr_no,
744+ } ,
745+ CInlineAsmOperand :: Out {
746+ reg: InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) ) ,
747+ late: true ,
748+ place: Some ( ret) ,
749+ } ,
750+ CInlineAsmOperand :: Out {
751+ reg: InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) ) ,
752+ late: true ,
753+ place: None ,
754+ } ,
755+ ] ;
756+ let options = InlineAsmOptions :: NOSTACK | InlineAsmOptions :: PURE | InlineAsmOptions :: NOMEM ;
757+
758+ let mut inputs = Vec :: new ( ) ;
759+ let mut outputs = Vec :: new ( ) ;
760+
761+ let mut asm_gen = InlineAssemblyGenerator {
762+ tcx : fx. tcx ,
763+ arch : fx. tcx . sess . asm_arch . unwrap ( ) ,
764+ enclosing_def_id : fx. instance . def_id ( ) ,
765+ template : & [ InlineAsmTemplatePiece :: String (
766+ "
767+ xgetbv
768+ // out = rdx << 32 | rax
769+ shl rdx, 32
770+ or rax, rdx
771+ "
772+ . to_string ( ) ,
773+ ) ] ,
774+ operands : & operands,
775+ options,
776+ registers : Vec :: new ( ) ,
777+ stack_slots_clobber : Vec :: new ( ) ,
778+ stack_slots_input : Vec :: new ( ) ,
779+ stack_slots_output : Vec :: new ( ) ,
780+ stack_slot_size : Size :: from_bytes ( 0 ) ,
781+ } ;
782+ asm_gen. allocate_registers ( ) ;
783+ asm_gen. allocate_stack_slots ( ) ;
784+
785+ let inline_asm_index = fx. cx . inline_asm_index . get ( ) ;
786+ fx. cx . inline_asm_index . set ( inline_asm_index + 1 ) ;
787+ let asm_name = format ! (
788+ "__inline_asm_{}_n{}" ,
789+ fx. cx. cgu_name. as_str( ) . replace( '.' , "__" ) . replace( '-' , "_" ) ,
790+ inline_asm_index
791+ ) ;
792+
793+ let generated_asm = asm_gen. generate_asm_wrapper ( & asm_name) ;
794+ fx. cx . global_asm . push_str ( & generated_asm) ;
795+
796+ for ( i, operand) in operands. iter ( ) . enumerate ( ) {
797+ match operand {
798+ CInlineAsmOperand :: In { reg : _, value } => {
799+ inputs. push ( ( asm_gen. stack_slots_input [ i] . unwrap ( ) , * value) ) ;
800+ }
801+ CInlineAsmOperand :: Out { reg : _, late : _, place } => {
802+ if let Some ( place) = place {
803+ outputs. push ( ( asm_gen. stack_slots_output [ i] . unwrap ( ) , * place) ) ;
804+ }
805+ }
806+ _ => unreachable ! ( ) ,
807+ }
808+ }
809+
810+ call_inline_asm ( fx, & asm_name, asm_gen. stack_slot_size , inputs, outputs) ;
811+ }
0 commit comments