It turns out you can make a really fast instruction decoder in Scrap Mechanic if only you can figure out a special bit mask for each ALU operation. It turns out this is really frickity fucking hard to do by hand so I told a SAT solver to do it and it was fine until I asked for all the combinations I wanted and then... This.
out.dimacs is 36MB
c CNF file written by RustSAT
p cnf 217953 1366264
Also dimacs uses "c" for comments lol (it's just a huge file of numbers).
Also also it turns out using 100% of all 24 cores on a laptop for 8 hours makes for some heat issues so I had to limit each core to 50% utilization so it will take twice as long yay.
UPDATE: it's been 18 hours and the best it's got it 3.925%. If I linearly extrapolate, it will take 400-500 hours ≈ 2.5-3 weeks.
UPDATE 2: I've turned it off, as I don't have more than a weekend to just leave my laptop sitting around.
Based on my other comment, do you have any in mind that would be more appropriate?
I think a "constraint propagation" based solver should work well. So you can try using minizinc and play with the solvers it gives you. Using gecode and heuristics it can get very fast (try using relax_and_reconstruct, together with restart_luby and indomain_random, to obtain a simple LNS. Or you can use Google's OR tools solver, that is based on ILP and is very fast, and can run multithreaded.
You can also go fully ILP, and model your problem in ampl, and try some free (e.g. glpk) or commercial (e.g. gurobi) ILP solver.
I doubt it helps, but there's always SMT solvers (e.g. cvc5), which I don't think can be faster but is surely easier to model than a pure SAT. And there's also ASP solvers like clingo (clasp+gringo), that are purely logic based and implement common-sense-reasoning.