1
+ use std:: fs:: { self , File } ;
2
+ use std:: io:: { BufRead , BufReader } ;
3
+ use std:: path:: Path ;
4
+
5
+ use crate :: common:: intrinsic:: Intrinsic ;
6
+ use crate :: common:: intrinsic_helpers:: IntrinsicType ;
7
+ use crate :: loongarch:: intrinsic:: LoongArchIntrinsicType ;
8
+
9
+ pub fn get_loongson_intrinsics (
10
+ path : & Path ,
11
+ target : & str
12
+ ) -> Result < Vec < Intrinsic < LoongArchIntrinsicType > > , Box < dyn std:: error:: Error > > {
13
+ let f = File :: open ( path) . unwrap_or_else ( |_| panic ! ( "Failed to open {}" , path. display( ) ) ) ;
14
+ let f = BufReader :: new ( f) ;
15
+
16
+ let mut para_num;
17
+ let mut current_name: Option < String > = None ;
18
+ let mut asm_fmts: Vec < String > = Vec :: new ( ) ;
19
+ let mut impl_function_str = String :: new ( ) ;
20
+ let mut call_function_str = String :: new ( ) ;
21
+ let mut out = String :: new ( ) ;
22
+
23
+ let mut intrinsics: Vec < Intrinsic < LoongArchIntrinsicType > > = Vec :: new ( ) ;
24
+ for line in f. lines ( ) {
25
+ let line = line. unwrap ( ) ;
26
+ if line. is_empty ( ) {
27
+ continue ;
28
+ }
29
+ if let Some ( name) = line. strip_prefix ( "name = " ) {
30
+ current_name = Some ( String :: from ( name) ) ;
31
+ } else if line. starts_with ( "asm-fmts = " ) {
32
+ asm_fmts = line[ 10 ..]
33
+ . split ( ',' )
34
+ . map ( |v| v. trim ( ) . to_string ( ) )
35
+ . collect ( ) ;
36
+ } else if line. starts_with ( "data-types = " ) {
37
+ let current_name = current_name. clone ( ) . unwrap ( ) ;
38
+ let data_types: Vec < & str > = line
39
+ . get ( 12 ..)
40
+ . unwrap ( )
41
+ . split ( ',' )
42
+ . map ( |e| e. trim ( ) )
43
+ . collect ( ) ;
44
+ let in_t;
45
+ let out_t;
46
+ if data_types. len ( ) == 2 {
47
+ in_t = [ data_types[ 1 ] , "NULL" , "NULL" , "NULL" ] ;
48
+ out_t = data_types[ 0 ] ;
49
+ para_num = 1 ;
50
+ } else if data_types. len ( ) == 3 {
51
+ in_t = [ data_types[ 1 ] , data_types[ 2 ] , "NULL" , "NULL" ] ;
52
+ out_t = data_types[ 0 ] ;
53
+ para_num = 2 ;
54
+ } else if data_types. len ( ) == 4 {
55
+ in_t = [ data_types[ 1 ] , data_types[ 2 ] , data_types[ 3 ] , "NULL" ] ;
56
+ out_t = data_types[ 0 ] ;
57
+ para_num = 3 ;
58
+ } else if data_types. len ( ) == 5 {
59
+ in_t = [ data_types[ 1 ] , data_types[ 2 ] , data_types[ 3 ] , data_types[ 4 ] ] ;
60
+ out_t = data_types[ 0 ] ;
61
+ para_num = 4 ;
62
+ } else {
63
+ panic ! ( "DEBUG: line: {0} len: {1}" , line, data_types. len( ) ) ;
64
+ }
65
+
66
+ // TODO: implement the below functions
67
+ // create list of intrinsics
68
+ let intrinsic = gen_intrinsic ( current_name. as_str ( ) , asm_fmts. as_slice ( ) , & in_t, out_t, para_num, target) ;
69
+ if intrinsic. is_ok ( ) {
70
+ intrinsics. push ( intrinsic. unwrap ( ) ) ;
71
+ }
72
+ }
73
+ } ;
74
+ return Ok ( intrinsics)
75
+ }
76
+
77
+ fn gen_intrinsic (
78
+ current_name : & str ,
79
+ asm_fmts : & [ String ] ,
80
+ in_t : & [ & str ; 4 ] ,
81
+ out_t : & str ,
82
+ para_num : i32 ,
83
+ target : & str ,
84
+ ) -> Result < Intrinsic < LoongArchIntrinsicType > , Box < dyn std:: error:: Error > > {
85
+ let type_to_ct = |t : & str | -> & str {
86
+ match t {
87
+ "V16QI" => "union v16qi" ,
88
+ "V32QI" => "union v32qi" ,
89
+ "V8HI" => "union v8hi" ,
90
+ "V16HI" => "union v16hi" ,
91
+ "V4SI" => "union v4si" ,
92
+ "V8SI" => "union v8si" ,
93
+ "V2DI" => "union v2di" ,
94
+ "V4DI" => "union v4di" ,
95
+ "UV16QI" => "union uv16qi" ,
96
+ "UV32QI" => "union uv32qi" ,
97
+ "UV8HI" => "union uv8hi" ,
98
+ "UV16HI" => "union uv16hi" ,
99
+ "UV4SI" => "union uv4si" ,
100
+ "UV8SI" => "union uv8si" ,
101
+ "UV2DI" => "union uv2di" ,
102
+ "UV4DI" => "union uv4di" ,
103
+ "SI" => "int32_t" ,
104
+ "DI" => "int64_t" ,
105
+ "USI" => "uint32_t" ,
106
+ "UDI" => "uint64_t" ,
107
+ "V4SF" => "union v4sf" ,
108
+ "V8SF" => "union v8sf" ,
109
+ "V2DF" => "union v2df" ,
110
+ "V4DF" => "union v4df" ,
111
+ "UQI" => "uint32_t" ,
112
+ "QI" => "int32_t" ,
113
+ "CVPOINTER" => "void*" ,
114
+ "HI" => "int32_t" ,
115
+ _ => panic ! ( "unknown type: {t}" ) ,
116
+ }
117
+ } ;
118
+ let type_to_size = |v : & str , t : & str | -> u32 {
119
+ let n = if v. starts_with ( '_' ) {
120
+ v. get ( 1 ..) . unwrap ( )
121
+ } else {
122
+ v
123
+ } ;
124
+ match t {
125
+ "A16QI" => 8 ,
126
+ "AM16QI" => 8 ,
127
+ "V16QI" => 8 ,
128
+ "V32QI" => 8 ,
129
+ "A32QI" => 8 ,
130
+ "AM32QI" => 8 ,
131
+ "V8HI" => 16 ,
132
+ "V16HI" => 16 ,
133
+ "V4SI" => 32 ,
134
+ "V8SI" => 32 ,
135
+ "V2DI" => 64 ,
136
+ "V4DI" => 64 ,
137
+ "UV16QI" => 8 ,
138
+ "UV32QI" => 8 ,
139
+ "UV8HI" => 16 ,
140
+ "UV16HI" => 16 ,
141
+ "UV4SI" => 32 ,
142
+ "UV8SI" => 32 ,
143
+ "UV2DI" => 64 ,
144
+ "UV4DI" => 64 ,
145
+ "V4SF" => 32 ,
146
+ "V8SF" => 32 ,
147
+ "V2DF" => 64 ,
148
+ "V4DF" => 64 ,
149
+ "SI" | "DI" | "USI" | "UDI" | "UQI" | "QI" | "CVPOINTER" | "HI" => 0 ,
150
+ _ => panic ! ( "unknown type: {t}" ) ,
151
+ }
152
+ } ;
153
+ let type_to_rp = |t : & str | -> Option < u32 > {
154
+ match t {
155
+ "SI" | "DI" | "USI" | "UDI" | "UQI" | "QI" | "HI" | => None ,
156
+ "V32QI" | "V16HI" | "V8SI" | "V4DI" | "UV32QI" | "UV16HI" | "UV8SI" | "UV4DI"
157
+ | "V8SF" | "V4DF" => Some ( 4 )
158
+ _ => Some ( 2 ) ,
159
+ }
160
+ } ;
161
+ let type_to_imm = |t| -> i8 {
162
+ match t {
163
+ 'b' => 4 ,
164
+ 'h' => 3 ,
165
+ 'w' => 2 ,
166
+ 'd' => 1 ,
167
+ _ => panic ! ( "unsupported type" ) ,
168
+ }
169
+ } ;
170
+
171
+ Ok ( Intrinsic {
172
+ name : current_name. to_string ( ) ,
173
+ arguments,
174
+ results : results,
175
+ arch_tags : vec ! [ target. to_string( ) ] ,
176
+ } )
177
+ }
0 commit comments