1
- use std:: fs:: { self , File } ;
1
+ use std:: fs:: File ;
2
2
use std:: io:: { BufRead , BufReader } ;
3
3
use std:: path:: Path ;
4
4
5
+ use crate :: common:: argument:: { Argument , ArgumentList } ;
5
6
use crate :: common:: intrinsic:: Intrinsic ;
6
- use crate :: common:: intrinsic_helpers:: IntrinsicType ;
7
7
use crate :: loongarch:: intrinsic:: LoongArchIntrinsicType ;
8
8
9
9
pub fn get_loongson_intrinsics (
@@ -13,12 +13,8 @@ pub fn get_loongson_intrinsics(
13
13
let f = File :: open ( path) . unwrap_or_else ( |_| panic ! ( "Failed to open {}" , path. display( ) ) ) ;
14
14
let f = BufReader :: new ( f) ;
15
15
16
- let mut para_num;
17
16
let mut current_name: Option < String > = None ;
18
17
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
18
23
19
let mut intrinsics: Vec < Intrinsic < LoongArchIntrinsicType > > = Vec :: new ( ) ;
24
20
for line in f. lines ( ) {
@@ -35,37 +31,25 @@ pub fn get_loongson_intrinsics(
35
31
. collect ( ) ;
36
32
} else if line. starts_with ( "data-types = " ) {
37
33
let current_name = current_name. clone ( ) . unwrap ( ) ;
38
- let data_types: Vec < & str > = line
34
+ let mut data_types: Vec < String > = line
39
35
. get ( 12 ..)
40
36
. unwrap ( )
41
37
. split ( ',' )
42
- . map ( |e| e. trim ( ) )
38
+ . map ( |e| e. trim ( ) . to_string ( ) )
43
39
. 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 {
40
+ let arguments;
41
+ let return_type;
42
+ let data_types_len = data_types. len ( ) ;
43
+ if data_types_len > 0 && data_types_len < 6 {
44
+ arguments = data_types. split_off ( 1 ) ;
45
+
46
+ // Being explicit here with the variable name
47
+ return_type = data_types. get ( 0 ) . unwrap ( ) ;
48
+ } else {
63
49
panic ! ( "DEBUG: line: {0} len: {1}" , line, data_types. len( ) ) ;
64
50
}
65
51
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) ;
52
+ let intrinsic = gen_intrinsic ( current_name. as_str ( ) , asm_fmts. clone ( ) , arguments, return_type, target) ;
69
53
if intrinsic. is_ok ( ) {
70
54
intrinsics. push ( intrinsic. unwrap ( ) ) ;
71
55
}
@@ -76,98 +60,72 @@ pub fn get_loongson_intrinsics(
76
60
77
61
fn gen_intrinsic (
78
62
current_name : & str ,
79
- asm_fmts : & [ String ] ,
80
- in_t : & [ & str ; 4 ] ,
81
- out_t : & str ,
82
- para_num : i32 ,
63
+ asm_fmts : Vec < String > ,
64
+ args : Vec < String > ,
65
+ return_type : & String ,
83
66
target : & str ,
84
67
) -> 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 ( )
68
+ let para_num = args. len ( ) ;
69
+ let mut arguments = asm_fmts
70
+ . iter ( )
71
+ . zip ( args. iter ( ) )
72
+ . enumerate ( )
73
+ . map ( |( i, ( asm_fmt, arg_type) ) | {
74
+ let ty = LoongArchIntrinsicType :: from_values ( asm_fmt, arg_type) . unwrap ( ) ;
75
+ let arg = Argument :: < LoongArchIntrinsicType > :: new ( i, format ! ( "_{i}_{}" , arg_type) , ty, None ) ;
76
+ return arg;
77
+ } )
78
+ . collect :: < Vec < Argument < LoongArchIntrinsicType > > > ( ) ;
79
+
80
+ if para_num == 1 && args[ 0 ] == "HI" {
81
+ match asm_fmts[ 1 ] . as_str ( ) {
82
+ "si13" | "i13" => arguments[ 0 ] . ty . constant = true ,
83
+ "si10" => arguments[ 0 ] . ty . constant = true ,
84
+ _ => panic ! ( "unsupported assembly format: {:?}" , asm_fmts) ,
85
+ } ;
86
+ } else if para_num == 2 && ( args[ 1 ] == "UQI" || args[ 1 ] == "USI" ) {
87
+ if asm_fmts[ 2 ] . starts_with ( "ui" ) {
88
+ arguments[ 1 ] . ty . constant = true ;
121
89
} else {
122
- v
90
+ panic ! ( "unsupported assembly format: {:?}" , asm_fmts ) ;
123
91
} ;
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
-
92
+ } else if para_num == 2 && args[ 1 ] == "QI" {
93
+ if asm_fmts[ 2 ] . starts_with ( "si" ) {
94
+ arguments[ 1 ] . ty . constant = true ;
95
+ } else {
96
+ panic ! ( "unsupported assembly format: {:?}" , asm_fmts) ;
97
+ } ;
98
+ } else if para_num == 2 && args[ 0 ] == "CVPOINTER" && args[ 1 ] == "SI" {
99
+ if asm_fmts[ 2 ] . starts_with ( "si" ) {
100
+ arguments[ 1 ] . ty . constant = true ;
101
+ } else {
102
+ panic ! ( "unsupported assembly format: {:?}" , asm_fmts) ;
103
+ } ;
104
+ } else if para_num == 3 && ( args[ 2 ] == "USI" || args[ 2 ] == "UQI" ) {
105
+ if asm_fmts[ 2 ] . starts_with ( "ui" ) {
106
+ arguments[ 2 ] . ty . constant = true ;
107
+ } else {
108
+ panic ! ( "unsupported assembly format: {:?}" , asm_fmts) ;
109
+ } ;
110
+ } else if para_num == 3 && args[ 1 ] == "CVPOINTER" && args[ 2 ] == "SI" {
111
+ match asm_fmts[ 2 ] . as_str ( ) {
112
+ "si12" => arguments[ 2 ] . ty . constant = true ,
113
+ _ => panic ! ( "unsupported assembly format: {:?}" , asm_fmts) ,
114
+ } ;
115
+ } else if para_num == 4 {
116
+ match ( asm_fmts[ 3 ] . as_str ( ) , current_name. chars ( ) . last ( ) . unwrap ( ) ) {
117
+ ( "si8" , t) => {
118
+ arguments[ 2 ] . ty . constant = true ;
119
+ arguments[ 3 ] . ty . constant = true ;
120
+ } ,
121
+ ( _, _) => panic ! (
122
+ "unsupported assembly format: {:?} for {}" ,
123
+ asm_fmts, current_name
124
+ ) ,
125
+ } ;
126
+ }
127
+ let results = LoongArchIntrinsicType :: from_values ( return_type, & asm_fmts[ 0 ] ) ?;
128
+ let arguments = ArgumentList :: < LoongArchIntrinsicType > { args : arguments } ;
171
129
Ok ( Intrinsic {
172
130
name : current_name. to_string ( ) ,
173
131
arguments,
0 commit comments