@@ -20,10 +20,14 @@ pub(crate) fn codegen_inline_asm<'tcx>(
20
20
// FIXME add .eh_frame unwind info directives
21
21
22
22
if !template. is_empty ( ) {
23
+ // Used by panic_abort
23
24
if template[ 0 ] == InlineAsmTemplatePiece :: String ( "int $$0x29" . to_string ( ) ) {
24
25
fx. bcx . ins ( ) . trap ( TrapCode :: User ( 1 ) ) ;
25
26
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 ( ) )
27
31
&& matches ! (
28
32
template[ 1 ] ,
29
33
InlineAsmTemplatePiece :: Placeholder {
@@ -47,51 +51,46 @@ pub(crate) fn codegen_inline_asm<'tcx>(
47
51
{
48
52
assert_eq ! ( operands. len( ) , 4 ) ;
49
53
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
+ ) ,
60
63
_ => unreachable ! ( ) ,
61
64
} ;
62
65
let ebx_place = match operands[ 0 ] {
63
- InlineAsmOperand :: Out { reg, late : true , place } => {
64
- assert_eq ! (
65
- reg,
66
+ InlineAsmOperand :: Out {
67
+ reg :
66
68
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 ) ,
72
74
_ => unreachable ! ( ) ,
73
75
} ;
74
76
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
+ ) ,
85
86
_ => unreachable ! ( ) ,
86
87
} ;
87
88
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) ,
95
94
_ => unreachable ! ( ) ,
96
95
} ;
97
96
@@ -104,14 +103,97 @@ pub(crate) fn codegen_inline_asm<'tcx>(
104
103
let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
105
104
fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
106
105
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" ) {
108
110
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
109
111
crate :: trap:: trap_unimplemented ( fx, "Stack probes are not supported" ) ;
110
112
return ;
111
113
} else if fx. tcx . symbol_name ( fx. instance ) . name == "__alloca" {
112
114
crate :: trap:: trap_unimplemented ( fx, "Alloca is not supported" ) ;
113
115
return ;
114
116
}
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
+ }
115
197
}
116
198
117
199
let mut inputs = Vec :: new ( ) ;
0 commit comments