1- use crate :: program:: { Instruction , Reg } ;
1+ use crate :: program:: { Instruction , RawReg , Reg } ;
22use crate :: utils:: { parse_imm, parse_immediate, parse_reg, ParsedImmediate } ;
33use alloc:: borrow:: ToOwned ;
44use alloc:: collections:: BTreeMap ;
@@ -437,69 +437,29 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
437437 }
438438 }
439439
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( ) ) ) ;
475459 }
476460 }
477461 }
478462
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-
503463 if let Some ( src) = parse_reg ( rhs) {
504464 emit_and_continue ! ( Instruction :: move_reg( dst. into( ) , src. into( ) ) ) ;
505465 }
@@ -519,14 +479,9 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
519479 emit_and_continue ! ( MaybeInstruction :: LoadLabelAddress ( dst, label. to_owned( ) ) ) ;
520480 }
521481
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 ( ) , "^" ) {
530485 if let Some ( src1) = parse_reg ( src1) {
531486 if let Some ( src2) = parse_reg ( src2) {
532487 let dst = dst. into ( ) ;
@@ -884,45 +839,24 @@ pub fn assemble(code: &str) -> Result<Vec<u8>, String> {
884839 }
885840 }
886841
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+ }
926860 }
927861 }
928862 }
0 commit comments