| 2768 | |
| 2769 | #define FAILURES_LIMIT 10000 |
| 2770 | int assemble_single(string src, uint32_t addr, uint8_t *result, string& err, |
| 2771 | int& failures) |
| 2772 | { |
| 2773 | int rc = -1; |
| 2774 | |
| 2775 | /* decompose instruction into tokens */ |
| 2776 | vector<token> toks_src; |
| 2777 | vector<token> toks_child; |
| 2778 | |
| 2779 | if(tokenize(src, toks_src, err)) { |
| 2780 | err += "invalid syntax in " + src; |
| 2781 | return -1; |
| 2782 | } |
| 2783 | |
| 2784 | /* form signature, look it up */ |
| 2785 | string sig_src = tokens_to_signature(toks_src); |
| 2786 | |
| 2787 | MYLOG("src:%s has signature:%s\n", src.c_str(), sig_src.c_str()); |
| 2788 | |
| 2789 | if(lookup.find(sig_src) == lookup.end()) { |
| 2790 | err = "invalid syntax in " + sig_src; |
| 2791 | return -1; |
| 2792 | } |
| 2793 | |
| 2794 | auto info = lookup[sig_src]; |
| 2795 | uint32_t vary_mask = info.mask; |
| 2796 | |
| 2797 | /* for relative branches, shift the target address to 0 */ |
| 2798 | if(toks_src[0].sval[0]=='b' && toks_src[0].sval.back() != 'a' && |
| 2799 | toks_src.back().type == TT_NUM) { |
| 2800 | toks_src.back().ival -= addr; |
| 2801 | addr = 0; |
| 2802 | } |
| 2803 | else if(!strncmp("subis", toks_src[0].sval.c_str(), 6) && |
| 2804 | toks_src.back().type == TT_NUM) { |
| 2805 | toks_src.back().ival = -toks_src.back().ival; |
| 2806 | toks_src[0].sval = "addis"; |
| 2807 | } |
| 2808 | |
| 2809 | /* start with the parent */ |
| 2810 | uint32_t parent = info.seed; |
| 2811 | float init_score, top_score; |
| 2812 | init_score = top_score = score(toks_src, parent, addr); |
| 2813 | |
| 2814 | /* cache the xor masks */ |
| 2815 | int n_flips = 0; |
| 2816 | int flipper_idx[32]; |
| 2817 | uint32_t flipper[32]; |
| 2818 | for(int i=0; i<32; ++i) { |
| 2819 | if(vary_mask & (1 << i)) { |
| 2820 | flipper_idx[n_flips] = i; |
| 2821 | flipper[n_flips++] = 1<<i; |
| 2822 | } |
| 2823 | } |
| 2824 | |
| 2825 | failures = 0; |
| 2826 | int failstreak = 0; |
| 2827 | |