1- use std:: fs:: { self , File } ;
1+ use std:: fs:: File ;
22use std:: io:: { BufRead , BufReader } ;
33use std:: path:: Path ;
44
5+ use crate :: common:: argument:: { Argument , ArgumentList } ;
56use crate :: common:: intrinsic:: Intrinsic ;
6- use crate :: common:: intrinsic_helpers:: IntrinsicType ;
77use crate :: loongarch:: intrinsic:: LoongArchIntrinsicType ;
88
99pub fn get_loongson_intrinsics (
@@ -13,12 +13,8 @@ pub fn get_loongson_intrinsics(
1313 let f = File :: open ( path) . unwrap_or_else ( |_| panic ! ( "Failed to open {}" , path. display( ) ) ) ;
1414 let f = BufReader :: new ( f) ;
1515
16- let mut para_num;
1716 let mut current_name: Option < String > = None ;
1817 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 ( ) ;
2218
2319 let mut intrinsics: Vec < Intrinsic < LoongArchIntrinsicType > > = Vec :: new ( ) ;
2420 for line in f. lines ( ) {
@@ -35,37 +31,25 @@ pub fn get_loongson_intrinsics(
3531 . collect ( ) ;
3632 } else if line. starts_with ( "data-types = " ) {
3733 let current_name = current_name. clone ( ) . unwrap ( ) ;
38- let data_types: Vec < & str > = line
34+ let mut data_types: Vec < String > = line
3935 . get ( 12 ..)
4036 . unwrap ( )
4137 . split ( ',' )
42- . map ( |e| e. trim ( ) )
38+ . map ( |e| e. trim ( ) . to_string ( ) )
4339 . 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 {
6349 panic ! ( "DEBUG: line: {0} len: {1}" , line, data_types. len( ) ) ;
6450 }
6551
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) ;
6953 if intrinsic. is_ok ( ) {
7054 intrinsics. push ( intrinsic. unwrap ( ) ) ;
7155 }
@@ -76,98 +60,72 @@ pub fn get_loongson_intrinsics(
7660
7761fn gen_intrinsic (
7862 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 ,
8366 target : & str ,
8467) -> 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 ;
12189 } else {
122- v
90+ panic ! ( "unsupported assembly format: {:?}" , asm_fmts ) ;
12391 } ;
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 } ;
171129 Ok ( Intrinsic {
172130 name : current_name. to_string ( ) ,
173131 arguments,
0 commit comments