         [ [ dst>> ] [ src1>> ] bi ] [ log2 ] bi* \ ##shl-imm new-insn
         dup number-values
     ] [
-        drop dup \ ##mul-imm combine-imm?
-        [ [ * ] \ ##mul-imm combine-imm ] when
+        drop [ * ] \ ##mul-imm combine-imm
     ] if ;
 
-M: ##and-imm rewrite
-    dup \ ##and-imm combine-imm?
-    [ [ bitand ] \ ##and-imm combine-imm ] when ;
-
-M: ##or-imm rewrite
-    dup \ ##or-imm combine-imm?
-    [ [ bitor ] \ ##or-imm combine-imm ] when ;
-
-M: ##xor-imm rewrite
-    dup \ ##xor-imm combine-imm?
-    [ [ bitxor ] \ ##xor-imm combine-imm ] when ;
-
-: rewrite-add>add-imm? ( insn -- ? )
+M: ##and-imm rewrite [ bitand ] \ ##and-imm combine-imm ;
+
+M: ##or-imm rewrite [ bitor ] \ ##or-imm combine-imm ;
+
+M: ##xor-imm rewrite [ bitxor ] \ ##xor-imm combine-imm ;
+
+: rewrite-add? ( insn -- ? )
     src2>> {
         [ vreg>expr constant-expr? ]
         [ vreg>constant small-enough? ]
     } 1&& ;
 
 M: ##add rewrite
-    dup rewrite-add>add-imm? [
+    dup rewrite-add? [
         [ dst>> ]
         [ src1>> ]
         [ src2>> vreg>constant ] tri \ ##add-imm new-insn
         dup number-values
     ] when ;
+
+M: ##sub rewrite constant-fold ;

        } cleave
    ] [ call ] [ ] tri* new-imm-insn ; inline

M: ##add-imm rewrite
    {
        { [ dup \ ##add-imm combine-imm? ] [ [ + ] \ ##add-imm combine-imm ] }
        { [ dup \ ##sub-imm combine-imm? ] [ [ - ] \ ##sub-imm combine-imm ] }
        [ ]
    } cond ;

M: ##sub-imm rewrite
    {
        { [ dup \ ##add-imm combine-imm? ] [ [ - ] \ ##add-imm combine-imm ] }
        { [ dup \ ##sub-imm combine-imm? ] [ [ + ] \ ##sub-imm combine-imm ] }
        [ ]
    } cond ;


        ] when
    ] when ;

: constant-fold ( insn -- insn' )
    dup dst>> vreg>expr dup constant-expr? [
        [ dst>> ] [ value>> ] bi* \ ##load-immediate new-insn
        dup number-values
    ] [
        drop
    ] if ;

: (new-imm-insn) ( insn dst src1 n op -- new-insn/insn )
    [ cell-bits bits ] dip over small-enough? [
        new-insn dup number-values nip
    ] [
        2drop 2drop
    ] if constant-fold ; inline

: new-imm-insn ( insn dst src n op -- n' op' )
    2dup [ sgn ] dip 2array
