1
- use crate :: program:: { Instruction , Reg } ;
1
+ use crate :: program:: { Instruction , RawReg , Reg } ;
2
2
use crate :: utils:: { parse_imm, parse_immediate, parse_reg, ParsedImmediate } ;
3
3
use alloc:: borrow:: ToOwned ;
4
4
use alloc:: collections:: BTreeMap ;
@@ -437,69 +437,29 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
437
437
}
438
438
}
439
439
440
- if let Some ( index) = rhs. find ( "cpop " ) {
441
- if let Some ( src) = parse_reg ( rhs[ index + 5 ..] . trim ( ) ) {
442
- match op_marker {
443
- OpMarker :: I32 => {
444
- emit_and_continue ! ( Instruction :: count_set_bits_32( dst. into( ) , src. into( ) ) ) ;
445
- }
446
- OpMarker :: NONE => {
447
- emit_and_continue ! ( Instruction :: count_set_bits_64( dst. into( ) , src. into( ) ) ) ;
448
- }
449
- }
450
- }
451
- }
452
-
453
- if let Some ( index) = rhs. find ( "clz " ) {
454
- if let Some ( src) = parse_reg ( rhs[ index + 4 ..] . trim ( ) ) {
455
- match op_marker {
456
- OpMarker :: I32 => {
457
- emit_and_continue ! ( Instruction :: count_leading_zero_bits_32( dst. into( ) , src. into( ) ) ) ;
458
- }
459
- OpMarker :: NONE => {
460
- emit_and_continue ! ( Instruction :: count_leading_zero_bits_64( dst. into( ) , src. into( ) ) ) ;
461
- }
462
- }
463
- }
464
- }
465
-
466
- if let Some ( index) = rhs. find ( "ctz " ) {
467
- if let Some ( src) = parse_reg ( rhs[ index + 4 ..] . trim ( ) ) {
468
- match op_marker {
469
- OpMarker :: I32 => {
470
- emit_and_continue ! ( Instruction :: count_trailing_zero_bits_32( dst. into( ) , src. into( ) ) ) ;
471
- }
472
- OpMarker :: NONE => {
473
- emit_and_continue ! ( Instruction :: count_trailing_zero_bits_64( dst. into( ) , src. into( ) ) ) ;
474
- }
440
+ if let Some ( ( name, rhs) ) = split ( rhs, " " ) {
441
+ if let Some ( src) = parse_reg ( rhs) {
442
+ type F = fn ( RawReg , RawReg ) -> Instruction ;
443
+ let ctor = match ( name, op_marker) {
444
+ ( "cpop" , OpMarker :: I32 ) => Some ( Instruction :: count_set_bits_32 as F ) ,
445
+ ( "cpop" , OpMarker :: NONE ) => Some ( Instruction :: count_set_bits_64 as F ) ,
446
+ ( "clz" , OpMarker :: I32 ) => Some ( Instruction :: count_leading_zero_bits_32 as F ) ,
447
+ ( "clz" , OpMarker :: NONE ) => Some ( Instruction :: count_leading_zero_bits_64 as F ) ,
448
+ ( "ctz" , OpMarker :: I32 ) => Some ( Instruction :: count_trailing_zero_bits_32 as F ) ,
449
+ ( "ctz" , OpMarker :: NONE ) => Some ( Instruction :: count_trailing_zero_bits_64 as F ) ,
450
+ ( "sext.b" , _) => Some ( Instruction :: sign_extend_8 as F ) ,
451
+ ( "sext.h" , _) => Some ( Instruction :: sign_extend_16 as F ) ,
452
+ ( "zext.h" , _) => Some ( Instruction :: zero_extend_16 as F ) ,
453
+ ( "reverse" , _) => Some ( Instruction :: reverse_byte as F ) ,
454
+ _ => None ,
455
+ } ;
456
+
457
+ if let Some ( ctor) = ctor {
458
+ emit_and_continue ! ( ctor( dst. into( ) , src. into( ) ) ) ;
475
459
}
476
460
}
477
461
}
478
462
479
- if let Some ( index) = rhs. find ( "sext.b " ) {
480
- if let Some ( src) = parse_reg ( rhs[ index + 7 ..] . trim ( ) ) {
481
- emit_and_continue ! ( Instruction :: sign_extend_8( dst. into( ) , src. into( ) ) ) ;
482
- }
483
- }
484
-
485
- if let Some ( index) = rhs. find ( "sext.h " ) {
486
- if let Some ( src) = parse_reg ( rhs[ index + 7 ..] . trim ( ) ) {
487
- emit_and_continue ! ( Instruction :: sign_extend_16( dst. into( ) , src. into( ) ) ) ;
488
- }
489
- }
490
-
491
- if let Some ( index) = rhs. find ( "zext.h " ) {
492
- if let Some ( src) = parse_reg ( rhs[ index + 7 ..] . trim ( ) ) {
493
- emit_and_continue ! ( Instruction :: zero_extend_16( dst. into( ) , src. into( ) ) ) ;
494
- }
495
- }
496
-
497
- if let Some ( index) = rhs. find ( "reverse " ) {
498
- if let Some ( src) = parse_reg ( rhs[ index + 8 ..] . trim ( ) ) {
499
- emit_and_continue ! ( Instruction :: reverse_byte( dst. into( ) , src. into( ) ) ) ;
500
- }
501
- }
502
-
503
463
if let Some ( src) = parse_reg ( rhs) {
504
464
emit_and_continue ! ( Instruction :: move_reg( dst. into( ) , src. into( ) ) ) ;
505
465
}
@@ -519,14 +479,9 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
519
479
emit_and_continue ! ( MaybeInstruction :: LoadLabelAddress ( dst, label. to_owned( ) ) ) ;
520
480
}
521
481
522
- if let Some ( index) = rhs. find ( "~(" ) {
523
- let rhs = rhs[ index + 2 ..] . trim ( ) ;
524
- if let Some ( index) = rhs. find ( ')' ) {
525
- let rhs = rhs[ ..index] . trim ( ) ;
526
- if let Some ( index) = rhs. find ( '^' ) {
527
- let src1 = rhs[ ..index] . trim ( ) ;
528
- let src2 = rhs[ index + 1 ..] . trim ( ) ;
529
-
482
+ if let Some ( rhs) = rhs. strip_prefix ( "~(" ) {
483
+ if let Some ( rhs) = rhs. strip_suffix ( ')' ) {
484
+ if let Some ( ( src1, src2) ) = split ( rhs. trim ( ) , "^" ) {
530
485
if let Some ( src1) = parse_reg ( src1) {
531
486
if let Some ( src2) = parse_reg ( src2) {
532
487
let dst = dst. into ( ) ;
@@ -884,45 +839,24 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
884
839
}
885
840
}
886
841
887
- enum MaxMinOp {
888
- Max ,
889
- MaxUnsigned ,
890
- Min ,
891
- MinUnsigned ,
892
- }
893
-
894
- #[ allow( clippy:: manual_map) ]
895
- let min_max_op = if let Some ( index) = rhs. find ( "maxs(" ) {
896
- Some ( ( index, 5 , MaxMinOp :: Max ) )
897
- } else if let Some ( index) = rhs. find ( "maxu(" ) {
898
- Some ( ( index, 5 , MaxMinOp :: MaxUnsigned ) )
899
- } else if let Some ( index) = rhs. find ( "mins(" ) {
900
- Some ( ( index, 5 , MaxMinOp :: Min ) )
901
- } else if let Some ( index) = rhs. find ( "minu(" ) {
902
- Some ( ( index, 5 , MaxMinOp :: MinUnsigned ) )
903
- } else {
904
- None
905
- } ;
906
-
907
- if let Some ( ( index, op_len, op) ) = min_max_op {
908
- let rhs = rhs[ index + op_len..] . trim ( ) ;
909
- if let Some ( index) = rhs. find ( ')' ) {
910
- let rhs = rhs[ ..index] . trim ( ) ;
911
- if let Some ( index) = rhs. find ( ',' ) {
912
- let src1 = rhs[ ..index] . trim ( ) ;
913
- let src2 = rhs[ index + 1 ..] . trim ( ) ;
914
-
915
- if let Some ( src1) = parse_reg ( src1) {
916
- if let Some ( src2) = parse_reg ( src2) {
917
- let dst = dst. into ( ) ;
918
- let src1 = src1. into ( ) ;
919
- let src2 = src2. into ( ) ;
920
- emit_and_continue ! ( match op {
921
- MaxMinOp :: Max => Instruction :: maximum( dst, src1, src2) ,
922
- MaxMinOp :: MaxUnsigned => Instruction :: maximum_unsigned( dst, src1, src2) ,
923
- MaxMinOp :: Min => Instruction :: minimum( dst, src1, src2) ,
924
- MaxMinOp :: MinUnsigned => Instruction :: minimum_unsigned( dst, src1, src2) ,
925
- } ) ;
842
+ if let Some ( rhs) = rhs. strip_suffix ( ')' ) {
843
+ let rhs = rhs. trim ( ) ;
844
+ if let Some ( ( name, rhs) ) = split ( rhs, "(" ) {
845
+ type F = fn ( RawReg , RawReg , RawReg ) -> Instruction ;
846
+ let ctor = match name {
847
+ "maxs" => Some ( Instruction :: maximum as F ) ,
848
+ "maxu" => Some ( Instruction :: maximum_unsigned as F ) ,
849
+ "mins" => Some ( Instruction :: minimum as F ) ,
850
+ "minu" => Some ( Instruction :: minimum_unsigned as F ) ,
851
+ _ => None ,
852
+ } ;
853
+
854
+ if let Some ( ctor) = ctor {
855
+ if let Some ( ( src1, src2) ) = split ( rhs, "," ) {
856
+ if let Some ( src1) = parse_reg ( src1) {
857
+ if let Some ( src2) = parse_reg ( src2) {
858
+ emit_and_continue ! ( ctor( dst. into( ) , src1. into( ) , src2. into( ) ) ) ;
859
+ }
926
860
}
927
861
}
928
862
}
0 commit comments