@@ -15,114 +15,118 @@ use builder::Builder;
15
15
use value:: Value ;
16
16
17
17
use rustc:: hir;
18
- use interfaces:: { BuilderMethods , ConstMethods , BaseTypeMethods } ;
18
+ use interfaces:: * ;
19
19
20
20
use mir:: place:: PlaceRef ;
21
21
use mir:: operand:: OperandValue ;
22
22
23
23
use std:: ffi:: CString ;
24
24
use libc:: { c_uint, c_char} ;
25
25
26
- // Take an inline assembly expression and splat it out via LLVM
27
- pub fn codegen_inline_asm (
28
- bx : & Builder < ' a , ' ll , ' tcx > ,
29
- ia : & hir:: InlineAsm ,
30
- outputs : Vec < PlaceRef < ' tcx , & ' ll Value > > ,
31
- mut inputs : Vec < & ' ll Value >
32
- ) -> bool {
33
- let mut ext_constraints = vec ! [ ] ;
34
- let mut output_types = vec ! [ ] ;
35
-
36
- // Prepare the output operands
37
- let mut indirect_outputs = vec ! [ ] ;
38
- for ( i, ( out, & place) ) in ia. outputs . iter ( ) . zip ( & outputs) . enumerate ( ) {
39
- if out. is_rw {
40
- inputs. push ( bx. load_operand ( place) . immediate ( ) ) ;
41
- ext_constraints. push ( i. to_string ( ) ) ;
26
+
27
+ impl AsmBuilderMethods < ' tcx > for Builder < ' a , ' ll , ' tcx > {
28
+ // Take an inline assembly expression and splat it out via LLVM
29
+ fn codegen_inline_asm (
30
+ & self ,
31
+ ia : & hir:: InlineAsm ,
32
+ outputs : Vec < PlaceRef < ' tcx , & ' ll Value > > ,
33
+ mut inputs : Vec < & ' ll Value >
34
+ ) -> bool {
35
+ let mut ext_constraints = vec ! [ ] ;
36
+ let mut output_types = vec ! [ ] ;
37
+
38
+ // Prepare the output operands
39
+ let mut indirect_outputs = vec ! [ ] ;
40
+ for ( i, ( out, & place) ) in ia. outputs . iter ( ) . zip ( & outputs) . enumerate ( ) {
41
+ if out. is_rw {
42
+ inputs. push ( self . load_operand ( place) . immediate ( ) ) ;
43
+ ext_constraints. push ( i. to_string ( ) ) ;
44
+ }
45
+ if out. is_indirect {
46
+ indirect_outputs. push ( self . load_operand ( place) . immediate ( ) ) ;
47
+ } else {
48
+ output_types. push ( place. layout . llvm_type ( self . cx ( ) ) ) ;
49
+ }
42
50
}
43
- if out. is_indirect {
44
- indirect_outputs. push ( bx. load_operand ( place) . immediate ( ) ) ;
45
- } else {
46
- output_types. push ( place. layout . llvm_type ( bx. cx ( ) ) ) ;
51
+ if !indirect_outputs. is_empty ( ) {
52
+ indirect_outputs. extend_from_slice ( & inputs) ;
53
+ inputs = indirect_outputs;
47
54
}
48
- }
49
- if !indirect_outputs. is_empty ( ) {
50
- indirect_outputs. extend_from_slice ( & inputs) ;
51
- inputs = indirect_outputs;
52
- }
53
55
54
- let clobbers = ia. clobbers . iter ( )
55
- . map ( |s| format ! ( "~{{{}}}" , & s) ) ;
56
-
57
- // Default per-arch clobbers
58
- // Basically what clang does
59
- let arch_clobbers = match & bx . sess ( ) . target . target . arch [ ..] {
60
- "x86" | "x86_64" => vec ! [ "~{dirflag}" , "~{fpsr}" , "~{flags}" ] ,
61
- "mips" | "mips64" => vec ! [ "~{$1}" ] ,
62
- _ => Vec :: new ( )
63
- } ;
64
-
65
- let all_constraints =
66
- ia. outputs . iter ( ) . map ( |out| out. constraint . to_string ( ) )
67
- . chain ( ia. inputs . iter ( ) . map ( |s| s. to_string ( ) ) )
68
- . chain ( ext_constraints)
69
- . chain ( clobbers)
70
- . chain ( arch_clobbers. iter ( ) . map ( |s| s. to_string ( ) ) )
71
- . collect :: < Vec < String > > ( ) . join ( "," ) ;
72
-
73
- debug ! ( "Asm Constraints: {}" , & all_constraints) ;
74
-
75
- // Depending on how many outputs we have, the return type is different
76
- let num_outputs = output_types. len ( ) ;
77
- let output_type = match num_outputs {
78
- 0 => bx . cx ( ) . type_void ( ) ,
79
- 1 => output_types[ 0 ] ,
80
- _ => bx . cx ( ) . type_struct ( & output_types, false )
81
- } ;
82
-
83
- let asm = CString :: new ( ia. asm . as_str ( ) . as_bytes ( ) ) . unwrap ( ) ;
84
- let constraint_cstr = CString :: new ( all_constraints) . unwrap ( ) ;
85
- let r = bx . inline_asm_call (
86
- asm. as_ptr ( ) ,
87
- constraint_cstr. as_ptr ( ) ,
88
- & inputs,
89
- output_type,
90
- ia. volatile ,
91
- ia. alignstack ,
92
- ia. dialect
93
- ) ;
94
- if r. is_none ( ) {
95
- return false ;
96
- }
97
- let r = r. unwrap ( ) ;
56
+ let clobbers = ia. clobbers . iter ( )
57
+ . map ( |s| format ! ( "~{{{}}}" , & s) ) ;
58
+
59
+ // Default per-arch clobbers
60
+ // Basically what clang does
61
+ let arch_clobbers = match & self . cx ( ) . sess ( ) . target . target . arch [ ..] {
62
+ "x86" | "x86_64" => vec ! [ "~{dirflag}" , "~{fpsr}" , "~{flags}" ] ,
63
+ "mips" | "mips64" => vec ! [ "~{$1}" ] ,
64
+ _ => Vec :: new ( )
65
+ } ;
66
+
67
+ let all_constraints =
68
+ ia. outputs . iter ( ) . map ( |out| out. constraint . to_string ( ) )
69
+ . chain ( ia. inputs . iter ( ) . map ( |s| s. to_string ( ) ) )
70
+ . chain ( ext_constraints)
71
+ . chain ( clobbers)
72
+ . chain ( arch_clobbers. iter ( ) . map ( |s| s. to_string ( ) ) )
73
+ . collect :: < Vec < String > > ( ) . join ( "," ) ;
74
+
75
+ debug ! ( "Asm Constraints: {}" , & all_constraints) ;
76
+
77
+ // Depending on how many outputs we have, the return type is different
78
+ let num_outputs = output_types. len ( ) ;
79
+ let output_type = match num_outputs {
80
+ 0 => self . cx ( ) . type_void ( ) ,
81
+ 1 => output_types[ 0 ] ,
82
+ _ => self . cx ( ) . type_struct ( & output_types, false )
83
+ } ;
84
+
85
+ let asm = CString :: new ( ia. asm . as_str ( ) . as_bytes ( ) ) . unwrap ( ) ;
86
+ let constraint_cstr = CString :: new ( all_constraints) . unwrap ( ) ;
87
+ let r = self . inline_asm_call (
88
+ asm. as_ptr ( ) ,
89
+ constraint_cstr. as_ptr ( ) ,
90
+ & inputs,
91
+ output_type,
92
+ ia. volatile ,
93
+ ia. alignstack ,
94
+ ia. dialect
95
+ ) ;
96
+ if r. is_none ( ) {
97
+ return false ;
98
+ }
99
+ let r = r. unwrap ( ) ;
98
100
99
- // Again, based on how many outputs we have
100
- let outputs = ia. outputs . iter ( ) . zip ( & outputs) . filter ( |& ( ref o, _) | !o. is_indirect ) ;
101
- for ( i, ( _, & place) ) in outputs. enumerate ( ) {
102
- let v = if num_outputs == 1 { r } else { bx . extract_value ( r, i as u64 ) } ;
103
- OperandValue :: Immediate ( v) . store ( bx , place) ;
104
- }
101
+ // Again, based on how many outputs we have
102
+ let outputs = ia. outputs . iter ( ) . zip ( & outputs) . filter ( |& ( ref o, _) | !o. is_indirect ) ;
103
+ for ( i, ( _, & place) ) in outputs. enumerate ( ) {
104
+ let v = if num_outputs == 1 { r } else { self . extract_value ( r, i as u64 ) } ;
105
+ OperandValue :: Immediate ( v) . store ( self , place) ;
106
+ }
105
107
106
- // Store mark in a metadata node so we can map LLVM errors
107
- // back to source locations. See #17552.
108
- unsafe {
109
- let key = "srcloc" ;
110
- let kind = llvm:: LLVMGetMDKindIDInContext ( bx . cx ( ) . llcx ,
111
- key. as_ptr ( ) as * const c_char , key. len ( ) as c_uint ) ;
108
+ // Store mark in a metadata node so we can map LLVM errors
109
+ // back to source locations. See #17552.
110
+ unsafe {
111
+ let key = "srcloc" ;
112
+ let kind = llvm:: LLVMGetMDKindIDInContext ( self . cx ( ) . llcx ,
113
+ key. as_ptr ( ) as * const c_char , key. len ( ) as c_uint ) ;
112
114
113
- let val: & ' ll Value = bx . cx ( ) . const_i32 ( ia. ctxt . outer ( ) . as_u32 ( ) as i32 ) ;
115
+ let val: & ' ll Value = self . cx ( ) . const_i32 ( ia. ctxt . outer ( ) . as_u32 ( ) as i32 ) ;
114
116
115
- llvm:: LLVMSetMetadata ( r, kind,
116
- llvm:: LLVMMDNodeInContext ( bx . cx ( ) . llcx , & val, 1 ) ) ;
117
- }
117
+ llvm:: LLVMSetMetadata ( r, kind,
118
+ llvm:: LLVMMDNodeInContext ( self . cx ( ) . llcx , & val, 1 ) ) ;
119
+ }
118
120
119
- return true ;
121
+ true
122
+ }
120
123
}
121
124
122
- pub fn codegen_global_asm < ' a , ' tcx > ( cx : & CodegenCx < ' a , ' tcx > ,
123
- ga : & hir:: GlobalAsm ) {
124
- let asm = CString :: new ( ga. asm . as_str ( ) . as_bytes ( ) ) . unwrap ( ) ;
125
- unsafe {
126
- llvm:: LLVMRustAppendModuleInlineAsm ( cx. llmod , asm. as_ptr ( ) ) ;
125
+ impl AsmMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
126
+ fn codegen_global_asm ( & self , ga : & hir:: GlobalAsm ) {
127
+ let asm = CString :: new ( ga. asm . as_str ( ) . as_bytes ( ) ) . unwrap ( ) ;
128
+ unsafe {
129
+ llvm:: LLVMRustAppendModuleInlineAsm ( self . llmod , asm. as_ptr ( ) ) ;
130
+ }
127
131
}
128
132
}
0 commit comments