@@ -27,19 +27,47 @@ const OPS: &[Inst<'_>] = pulley_interpreter::for_each_op!(define);
27
27
const EXTENDED_OPS : & [ Inst < ' _ > ] = pulley_interpreter:: for_each_extended_op!( define) ;
28
28
29
29
enum Operand < ' a > {
30
- Normal { name : & ' a str , ty : & ' a str } ,
31
- Writable { name : & ' a str , ty : & ' a str } ,
32
- TrapCode { name : & ' a str , ty : & ' a str } ,
33
- Binop { reg : & ' a str } ,
30
+ Normal {
31
+ name : & ' a str ,
32
+ ty : & ' a str ,
33
+ } ,
34
+ Writable {
35
+ name : & ' a str ,
36
+ ty : & ' a str ,
37
+ } ,
38
+ TrapCode {
39
+ name : & ' a str ,
40
+ ty : & ' a str ,
41
+ } ,
42
+ Binop {
43
+ dst : & ' a str ,
44
+ src1 : & ' a str ,
45
+ src2 : & ' a str ,
46
+ } ,
34
47
}
35
48
36
49
impl Inst < ' _ > {
37
50
fn operands ( & self ) -> impl Iterator < Item = Operand < ' _ > > {
38
51
self . fields
39
52
. iter ( )
40
53
. map ( |( name, ty) | match ( * name, * ty) {
41
- ( "operands" , "BinaryOperands < XReg >" ) => Operand :: Binop { reg : "XReg" } ,
42
- ( "operands" , "BinaryOperands < FReg >" ) => Operand :: Binop { reg : "FReg" } ,
54
+ ( "operands" , binop) => {
55
+ // Parse "BinaryOperands < A >"` as A/A/A
56
+ // Parse "BinaryOperands < A, B >"` as A/B/A
57
+ // Parse "BinaryOperands < A, B, C >"` as A/B/C
58
+ let mut parts = binop
59
+ . strip_prefix ( "BinaryOperands <" )
60
+ . unwrap ( )
61
+ . strip_suffix ( ">" )
62
+ . unwrap ( )
63
+ . trim ( )
64
+ . split ( ',' )
65
+ . map ( |x| x. trim ( ) ) ;
66
+ let dst = parts. next ( ) . unwrap ( ) ;
67
+ let src1 = parts. next ( ) . unwrap_or ( dst) ;
68
+ let src2 = parts. next ( ) . unwrap_or ( dst) ;
69
+ Operand :: Binop { dst, src1, src2 }
70
+ }
43
71
( "dst" , ty) => Operand :: Writable { name, ty } ,
44
72
( name, ty) => Operand :: Normal { name, ty } ,
45
73
} )
@@ -109,7 +137,7 @@ pub fn generate_rust(filename: &str, out_dir: &Path) -> Result<(), Error> {
109
137
pat. push_str ( "," ) ;
110
138
format_string. push_str ( & format ! ( " // trap={{{name}:?}}" ) ) ;
111
139
}
112
- Operand :: Binop { reg : _ } => {
140
+ Operand :: Binop { .. } => {
113
141
pat. push_str ( "dst, src1, src2," ) ;
114
142
format_string. push_str ( " {dst}, {src1}, {src2}" ) ;
115
143
locals. push_str ( & format ! ( "let dst = reg_name(*dst.to_reg());\n " ) ) ;
@@ -161,7 +189,7 @@ pub fn generate_rust(filename: &str, out_dir: &Path) -> Result<(), Error> {
161
189
}
162
190
}
163
191
Operand :: TrapCode { .. } => { }
164
- Operand :: Binop { reg : _ } => {
192
+ Operand :: Binop { .. } => {
165
193
pat. push_str ( "dst, src1, src2," ) ;
166
194
uses. push ( "src1" ) ;
167
195
uses. push ( "src2" ) ;
@@ -221,7 +249,7 @@ pub fn generate_rust(filename: &str, out_dir: &Path) -> Result<(), Error> {
221
249
pat. push_str ( "," ) ;
222
250
trap. push_str ( & format ! ( "sink.add_trap({name});\n " ) ) ;
223
251
}
224
- Operand :: Binop { reg : _ } => {
252
+ Operand :: Binop { .. } => {
225
253
pat. push_str ( "dst, src1, src2," ) ;
226
254
args. push_str (
227
255
"pulley_interpreter::regs::BinaryOperands::new(dst, src1, src2)," ,
@@ -265,10 +293,10 @@ pub fn generate_isle(filename: &str, out_dir: &Path) -> Result<(), Error> {
265
293
Operand :: Writable { name, ty } => {
266
294
isle. push_str ( & format ! ( "\n ({name} Writable{ty})" ) ) ;
267
295
}
268
- Operand :: Binop { reg } => {
269
- isle. push_str ( & format ! ( "\n (dst Writable{reg })" ) ) ;
270
- isle. push_str ( & format ! ( "\n (src1 {reg })" ) ) ;
271
- isle. push_str ( & format ! ( "\n (src2 {reg })" ) ) ;
296
+ Operand :: Binop { dst , src1 , src2 } => {
297
+ isle. push_str ( & format ! ( "\n (dst Writable{dst })" ) ) ;
298
+ isle. push_str ( & format ! ( "\n (src1 {src1 })" ) ) ;
299
+ isle. push_str ( & format ! ( "\n (src2 {src2 })" ) ) ;
272
300
}
273
301
}
274
302
}
@@ -303,13 +331,13 @@ pub fn generate_isle(filename: &str, out_dir: &Path) -> Result<(), Error> {
303
331
assert ! ( result. is_none( ) , "{} has >1 result" , inst. snake_name) ;
304
332
result = Some ( ty) ;
305
333
}
306
- Operand :: Binop { reg } => {
307
- isle. push_str ( & format ! ( "{reg } {reg }" ) ) ;
334
+ Operand :: Binop { dst , src1 , src2 } => {
335
+ isle. push_str ( & format ! ( "{src1 } {src2 }" ) ) ;
308
336
rule. push_str ( "src1 src2" ) ;
309
337
ops. push ( "src1" ) ;
310
338
ops. push ( "src2" ) ;
311
339
assert ! ( result. is_none( ) , "{} has >1 result" , inst. snake_name) ;
312
- result = Some ( reg ) ;
340
+ result = Some ( dst ) ;
313
341
}
314
342
}
315
343
isle. push_str ( " " ) ;
0 commit comments