@@ -20,10 +20,14 @@ pub(crate) fn codegen_inline_asm<'tcx>(
2020 // FIXME add .eh_frame unwind info directives
2121
2222 if !template. is_empty ( ) {
23+ // Used by panic_abort
2324 if template[ 0 ] == InlineAsmTemplatePiece :: String ( "int $$0x29" . to_string ( ) ) {
2425 fx. bcx . ins ( ) . trap ( TrapCode :: User ( 1 ) ) ;
2526 return ;
26- } else if template[ 0 ] == InlineAsmTemplatePiece :: String ( "movq %rbx, " . to_string ( ) )
27+ }
28+
29+ // Used by stdarch
30+ if template[ 0 ] == InlineAsmTemplatePiece :: String ( "movq %rbx, " . to_string ( ) )
2731 && matches ! (
2832 template[ 1 ] ,
2933 InlineAsmTemplatePiece :: Placeholder {
@@ -47,51 +51,46 @@ pub(crate) fn codegen_inline_asm<'tcx>(
4751 {
4852 assert_eq ! ( operands. len( ) , 4 ) ;
4953 let ( leaf, eax_place) = match operands[ 1 ] {
50- InlineAsmOperand :: InOut { reg, late : true , ref in_value, out_place } => {
51- assert_eq ! (
52- reg,
53- InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) )
54- ) ;
55- (
56- crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
57- crate :: base:: codegen_place ( fx, out_place. unwrap ( ) ) ,
58- )
59- }
54+ InlineAsmOperand :: InOut {
55+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) ) ,
56+ late : true ,
57+ ref in_value,
58+ out_place : Some ( out_place) ,
59+ } => (
60+ crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
61+ crate :: base:: codegen_place ( fx, out_place) ,
62+ ) ,
6063 _ => unreachable ! ( ) ,
6164 } ;
6265 let ebx_place = match operands[ 0 ] {
63- InlineAsmOperand :: Out { reg, late : true , place } => {
64- assert_eq ! (
65- reg,
66+ InlineAsmOperand :: Out {
67+ reg :
6668 InlineAsmRegOrRegClass :: RegClass ( InlineAsmRegClass :: X86 (
67- X86InlineAsmRegClass :: reg
68- ) )
69- ) ;
70- crate :: base :: codegen_place ( fx , place . unwrap ( ) )
71- }
69+ X86InlineAsmRegClass :: reg,
70+ ) ) ,
71+ late : true ,
72+ place : Some ( place ) ,
73+ } => crate :: base :: codegen_place ( fx , place ) ,
7274 _ => unreachable ! ( ) ,
7375 } ;
7476 let ( sub_leaf, ecx_place) = match operands[ 2 ] {
75- InlineAsmOperand :: InOut { reg, late : true , ref in_value, out_place } => {
76- assert_eq ! (
77- reg,
78- InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) )
79- ) ;
80- (
81- crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
82- crate :: base:: codegen_place ( fx, out_place. unwrap ( ) ) ,
83- )
84- }
77+ InlineAsmOperand :: InOut {
78+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) ) ,
79+ late : true ,
80+ ref in_value,
81+ out_place : Some ( out_place) ,
82+ } => (
83+ crate :: base:: codegen_operand ( fx, in_value) . load_scalar ( fx) ,
84+ crate :: base:: codegen_place ( fx, out_place) ,
85+ ) ,
8586 _ => unreachable ! ( ) ,
8687 } ;
8788 let edx_place = match operands[ 3 ] {
88- InlineAsmOperand :: Out { reg, late : true , place } => {
89- assert_eq ! (
90- reg,
91- InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) )
92- ) ;
93- crate :: base:: codegen_place ( fx, place. unwrap ( ) )
94- }
89+ InlineAsmOperand :: Out {
90+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) ) ,
91+ late : true ,
92+ place : Some ( place) ,
93+ } => crate :: base:: codegen_place ( fx, place) ,
9594 _ => unreachable ! ( ) ,
9695 } ;
9796
@@ -104,14 +103,97 @@ pub(crate) fn codegen_inline_asm<'tcx>(
104103 let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
105104 fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
106105 return ;
107- } else if fx. tcx . symbol_name ( fx. instance ) . name . starts_with ( "___chkstk" ) {
106+ }
107+
108+ // Used by compiler-builtins
109+ if fx. tcx . symbol_name ( fx. instance ) . name . starts_with ( "___chkstk" ) {
108110 // ___chkstk, ___chkstk_ms and __alloca are only used on Windows
109111 crate :: trap:: trap_unimplemented ( fx, "Stack probes are not supported" ) ;
110112 return ;
111113 } else if fx. tcx . symbol_name ( fx. instance ) . name == "__alloca" {
112114 crate :: trap:: trap_unimplemented ( fx, "Alloca is not supported" ) ;
113115 return ;
114116 }
117+
118+ // Used by measureme
119+ if template[ 0 ] == InlineAsmTemplatePiece :: String ( "xor %eax, %eax" . to_string ( ) )
120+ && template[ 1 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
121+ && template[ 2 ] == InlineAsmTemplatePiece :: String ( "mov %rbx, " . to_string ( ) )
122+ && matches ! (
123+ template[ 3 ] ,
124+ InlineAsmTemplatePiece :: Placeholder {
125+ operand_idx: 0 ,
126+ modifier: Some ( 'r' ) ,
127+ span: _
128+ }
129+ )
130+ && template[ 4 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
131+ && template[ 5 ] == InlineAsmTemplatePiece :: String ( "cpuid" . to_string ( ) )
132+ && template[ 6 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
133+ && template[ 7 ] == InlineAsmTemplatePiece :: String ( "mov " . to_string ( ) )
134+ && matches ! (
135+ template[ 8 ] ,
136+ InlineAsmTemplatePiece :: Placeholder {
137+ operand_idx: 0 ,
138+ modifier: Some ( 'r' ) ,
139+ span: _
140+ }
141+ )
142+ && template[ 9 ] == InlineAsmTemplatePiece :: String ( ", %rbx" . to_string ( ) )
143+ {
144+ let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
145+ fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
146+ return ;
147+ } else if template[ 0 ] == InlineAsmTemplatePiece :: String ( "rdpmc" . to_string ( ) ) {
148+ // Return zero dummy values for all performance counters
149+ match operands[ 0 ] {
150+ InlineAsmOperand :: In {
151+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: cx) ) ,
152+ value : _,
153+ } => { }
154+ _ => unreachable ! ( ) ,
155+ } ;
156+ let lo = match operands[ 1 ] {
157+ InlineAsmOperand :: Out {
158+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: ax) ) ,
159+ late : true ,
160+ place : Some ( place) ,
161+ } => crate :: base:: codegen_place ( fx, place) ,
162+ _ => unreachable ! ( ) ,
163+ } ;
164+ let hi = match operands[ 2 ] {
165+ InlineAsmOperand :: Out {
166+ reg : InlineAsmRegOrRegClass :: Reg ( InlineAsmReg :: X86 ( X86InlineAsmReg :: dx) ) ,
167+ late : true ,
168+ place : Some ( place) ,
169+ } => crate :: base:: codegen_place ( fx, place) ,
170+ _ => unreachable ! ( ) ,
171+ } ;
172+
173+ let u32_layout = fx. layout_of ( fx. tcx . types . u32 ) ;
174+ let zero = fx. bcx . ins ( ) . iconst ( types:: I32 , 0 ) ;
175+ lo. write_cvalue ( fx, CValue :: by_val ( zero, u32_layout) ) ;
176+ hi. write_cvalue ( fx, CValue :: by_val ( zero, u32_layout) ) ;
177+
178+ let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
179+ fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
180+ return ;
181+ } else if template[ 0 ] == InlineAsmTemplatePiece :: String ( "lock xadd " . to_string ( ) )
182+ && matches ! (
183+ template[ 1 ] ,
184+ InlineAsmTemplatePiece :: Placeholder { operand_idx: 1 , modifier: None , span: _ }
185+ )
186+ && template[ 2 ] == InlineAsmTemplatePiece :: String ( ", (" . to_string ( ) )
187+ && matches ! (
188+ template[ 3 ] ,
189+ InlineAsmTemplatePiece :: Placeholder { operand_idx: 0 , modifier: None , span: _ }
190+ )
191+ && template[ 4 ] == InlineAsmTemplatePiece :: String ( ")" . to_string ( ) )
192+ {
193+ let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
194+ fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
195+ return ;
196+ }
115197 }
116198
117199 let mut inputs = Vec :: new ( ) ;
0 commit comments