Commit 8c6a53cdc28c2e88e686d4ec35ef4281ee28b2ca
authorMichel Pollet <buserror@gmail.com>
Thu, 21 Sep 2017 09:52:29 +0000 (10:52 +0100)
committerMichel Pollet <buserror@gmail.com>
Wed, 10 Jan 2018 10:06:22 +0000 (10:06 +0000)
Removed unnecessary bits, like opcode if not needed. Also, strip
comments. Fix 32 bits instructions too.

Signed-off-by: Michel Pollet <buserror@gmail.com>
5 files changed:
simavr/Makefile
simavr/jit_emitter_generate.sh
simavr/sim/sim_core.c
simavr/sim/sim_core_jit.c
simavr/sim/sim_core_jit.h

index 6b94cd996a47f8375616c2e57f66b86acda757ed..2d1df80d3dff95e5b6261995fb9b11d1f6658422 100644 (file)
@@ -27,7 +27,7 @@ target        = run_avr
 CFLAGS += -Werror
 # tracing is useful especialy if you develop simavr core.
 # it otherwise eat quite a bit of few cycles, even disabled
-#CFLAGS        += -DCONFIG_SIMAVR_TRACE=1
+CFLAGS += -DCONFIG_SIMAVR_TRACE=1
 
 all:
        $(MAKE) obj config
index 46cc564f6b948800886153987eb1d19f10278eec..5bee9af5281fd7a1d205475f9c05fcbfb7f92f54 100755 (executable)
@@ -27,6 +27,7 @@ function quote(line) {
                accum = "";
                spewing = 0;
                sub(/emit/, "");
+               delete flags;
                print; next;
        }
 }
@@ -54,13 +55,23 @@ function quote(line) {
        if (!match($0, "#define")) {
                spewing = 1;
                sub(/end_emit/, "break");
-               print "jit_generate(opcode, " accum ");";
+               f = "0";
+               for (key in flags) f = f "+F_" key;
+               print "jit_generate(opcode, " f ","
+               print accum ");";
        }
 }
 {
        if (spewing)
                print;
        else {
+               if (match($0, /new_pc[ \t]*=/))
+                       flags["NO_PC"]++;
+               if (match($0, /opcode/))
+                       flags["OP"]++;
+               if (match($0, /TRACE_JUMP/))
+                       flags["JUMP"]++;
+               sub(/[ \t]*\/\/.*$/, "", $0);
                $0 = quote($0);
                accum = accum "\"" $0 "\\n\"" "\n";
        }
index 197fbc9beea0ee4168d1df55510cf6d57e427d29..23ba093b3808468bfad120aeeb2cd90c0d28c725 100644 (file)
@@ -1028,7 +1028,7 @@ run_one_again:
                                        }
                                        new_pc = _avr_pop_addr(avr);
                                        cycle += 1 + avr_address_size;
-                                       STATE("ret%s\n", opcode & 0x10 ? "i" : "");
+                                       STATE("ret%s [%04x]\n", opcode & 0x10 ? "i" : "", new_pc);
                                        TRACE_JUMP();
                                        STACK_FRAME_POP();
                                }       end_emit;
index dcf2ef49446d65651301b5491f32ed4ceeec89a2..ac5d0fb1776a4ec266146c6b4d9f791e99c2a125 100644 (file)
@@ -80,6 +80,12 @@ buf_add(
        buf_add_len(b, t, strlen(t));
 }
 
+enum {
+       F_NO_PC = (1 << 0),
+       F_OP = (1 << 1),
+       F_JUMP = (1 << 2),
+};
+
 avr_flashaddr_t
 avr_translate_firmware(
        avr_t * avr)
@@ -89,21 +95,25 @@ avr_translate_firmware(
 
        avr_flashaddr_t pc = 0;
 
-       void jit_generate_head(uint16_t o) {
+       void jit_generate_head(uint16_t o, uint8_t f) {
                char * b;
-               if (asprintf(&b, "f%04x: {\nconst uint16_t opcode = 0x%04x;\n", pc, o)) {};
+               if (asprintf(&b, "f%04x: {\n", pc)) {};
                buf_add(&code, b); free(b);
                buf_add(&code, "cycle++;");
-               if (asprintf(&b, "new_pc = 0x%04x + 2;\n", pc)) {};
-               buf_add(&code, b); free(b);
+       //      if (!(f & F_NO_PC)) {
+                       if (asprintf(&b, "new_pc = 0x%04x;\n", pc + 2)) {};
+                       buf_add(&code, b); free(b);
+       //      }
        //      if (asprintf(&b, "printf(\"%04x: %04x; cycle %%d/%%d\\n\",cycle,howLong);\n", pc, o));
        //      buf_add(&code, b); free(b);
                /* this is gcc/tcc 'label as value' C extension. Handy */
                if (asprintf(&b, "[0x%04x]= &&f%04x,\n", pc/2, pc)) {};
                buf_add(&jump_table, b); free(b);
        }
-       void jit_generate_tail(uint16_t o) {
-               buf_add(&code, "if (*is || cycle >= howLong) goto exit;\n}\n");
+       void jit_generate_tail(uint16_t o, uint8_t f) {
+               if (!(o & F_JUMP))
+                       buf_add(&code, "if (*is || cycle >= howLong) goto exit;");
+               buf_add(&code, "}\n");
        }
        void jit_generate_literal(const char * fmt, ...) {
                char * b;
@@ -121,20 +131,37 @@ avr_translate_firmware(
                        literal.b_len = 0;
                }
        }
-       void jit_generate(uint16_t o, const char * t) {
-               jit_generate_head(o);
+       void jit_generate(uint16_t o, uint8_t f, const char * t) {
+               char *dup = NULL;
+               if (f & F_OP) {
+                       char op[8];
+                       sprintf(op, "0x%04x", o);
+                       dup = strdup(t);
+                       t = dup;
+                       char * d;
+                       while ((d = strstr(t, "opcode")) != NULL)
+                               memcpy(d, op, 6);
+               }
+               jit_generate_head(o, f);
                jit_literal_flush();
                const char * l = t;
                do {
                        const char * nl = index(l, '\n');
-                       if (strncmp(l, "STATE", 5) || avr->trace)
-                               buf_add_len(&code, l, nl-l+1);
+                       int out = 1;
+                       int size = nl - l + 1;
+                       if (out) {
+                               out = (!strncmp(l, "STATE", 5) ||
+                                       !strncmp(l, "T(", 2)) ? avr->trace : 1;
+                       }
+                       if (out)
+                               buf_add_len(&code, l, size);
                        l = nl + 1;
                } while (*l);
-               jit_generate_tail(o);
+               jit_generate_tail(o, f);
+               if (dup) free(dup);
        }
        do {
-               avr_flashaddr_t new_pc = pc + 2;
+               avr_flashaddr_t new_pc = pc + 2 + (_avr_is_instruction_32_bits(avr, pc) ? 2 : 0);
                uint16_t opcode = _avr_flash_read16le(avr, pc);
                const int avr_rampz = avr->rampz;
                const int avr_eind = avr->eind;
index 6cfb341512c8328af912b4aa1f85924e5609ffd2..80d4fe901c6b3c9cef3734924794cffe3fbd38c5 100644 (file)
@@ -9,13 +9,15 @@
                case 0x0000: {
                        switch (opcode) {
                                case 0x0000:  { // NOP
-jit_generate(opcode, "STATE(\"nop\\n\");\n"
+jit_generate(opcode, 0,
+"STATE(\"nop\\n\");\n"
 );
                                }       break;
                                default: {
                                        switch (opcode & 0xfc00) {
                                                case 0x0400:  { // CPC -- Compare with carry -- 0000 01rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd - vr - SREG_BIT(S_C);\n"
 "STATE(\"cpc %s[%02x], %s[%02x] = %02x\\n\", avr_regname(d), vd, avr_regname(r), vr, res);\n"
 "_sreg = _avr_flags_sub_Rzns(_sreg, res, vd, vr);\n"
@@ -23,7 +25,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                                }       break;
                                                case 0x0c00:  { // ADD -- Add without carry -- 0000 11rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd + vr;\n"
 "if (r == d) {\n"
 "STATE(\"lsl %s[%02x] = %02x\\n\", avr_regname(d), vd, res & 0xff);\n"
@@ -36,7 +39,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                                }       break;
                                                case 0x0800:  { // SBC -- Subtract with carry -- 0000 10rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd - vr - SREG_BIT(S_C);\n"
 "STATE(\"sbc %s[%02x], %s[%02x] = %02x\\n\", avr_regname(d), avr_data[d], avr_regname(r), avr_data[r], res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -47,7 +51,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
                                                default:
                                                        switch (opcode & 0xff00) {
                                                                case 0x0100:  { // MOVW -- Copy Register Word -- 0000 0001 dddd rrrr
-jit_generate(opcode, "uint8_t d = ((opcode >> 4) & 0xf) << 1;\n"
+jit_generate(opcode, 0+F_OP,
+"uint8_t d = ((opcode >> 4) & 0xf) << 1;\n"
 "uint8_t r = ((opcode) & 0xf) << 1;\n"
 "STATE(\"movw %s:%s, %s:%s[%02x%02x]\\n\", avr_regname(d), avr_regname(d+1), avr_regname(r), avr_regname(r+1), avr_data[r+1], avr_data[r]);\n"
 "uint16_t vr = avr_data[r] | (avr_data[r + 1] << 8);\n"
@@ -55,7 +60,8 @@ jit_generate(opcode, "uint8_t d = ((opcode >> 4) & 0xf) << 1;\n"
 );
                                                                }       break;
                                                                case 0x0200:  { // MULS -- Multiply Signed -- 0000 0010 dddd rrrr
-jit_generate(opcode, "int8_t r = 16 + (opcode & 0xf);\n"
+jit_generate(opcode, 0+F_OP,
+"int8_t r = 16 + (opcode & 0xf);\n"
 "int8_t d = 16 + ((opcode >> 4) & 0xf);\n"
 "int16_t res = ((int8_t)avr_data[r]) * ((int8_t)avr_data[d]);\n"
 "STATE(\"muls %s[%d], %s[%02x] = %d\\n\", avr_regname(d), ((int8_t)avr_data[d]), avr_regname(r), ((int8_t)avr_data[r]), res);\n"
@@ -67,30 +73,31 @@ jit_generate(opcode, "int8_t r = 16 + (opcode & 0xf);\n"
 );
                                                                }       break;
                                                                case 0x0300:  { // MUL -- Multiply -- 0000 0011 fddd frrr
-jit_generate(opcode, "int8_t r = 16 + (opcode & 0x7);\n"
+jit_generate(opcode, 0+F_OP,
+"int8_t r = 16 + (opcode & 0x7);\n"
 "int8_t d = 16 + ((opcode >> 4) & 0x7);\n"
 "int16_t res = 0;\n"
 "uint8_t c = 0;\n"
 "T(const char * name = \"\";)\n"
 "switch (opcode & 0x88) {\n"
-"case 0x00:    // MULSU -- Multiply Signed Unsigned -- 0000 0011 0ddd 0rrr\n"
+"case 0x00:\n"
 "res = ((uint8_t)avr_data[r]) * ((int8_t)avr_data[d]);\n"
 "c = (res >> 15) & 1;\n"
 "T(name = \"mulsu\";)\n"
 "break;\n"
-"case 0x08:    // FMUL -- Fractional Multiply Unsigned -- 0000 0011 0ddd 1rrr\n"
+"case 0x08:\n"
 "res = ((uint8_t)avr_data[r]) * ((uint8_t)avr_data[d]);\n"
 "c = (res >> 15) & 1;\n"
 "res <<= 1;\n"
 "T(name = \"fmul\";)\n"
 "break;\n"
-"case 0x80:    // FMULS -- Multiply Signed -- 0000 0011 1ddd 0rrr\n"
+"case 0x80:\n"
 "res = ((int8_t)avr_data[r]) * ((int8_t)avr_data[d]);\n"
 "c = (res >> 15) & 1;\n"
 "res <<= 1;\n"
 "T(name = \"fmuls\";)\n"
 "break;\n"
-"case 0x88:    // FMULSU -- Multiply Signed Unsigned -- 0000 0011 1ddd 1rrr\n"
+"case 0x88:\n"
 "res = ((uint8_t)avr_data[r]) * ((int8_t)avr_data[d]);\n"
 "c = (res >> 15) & 1;\n"
 "res <<= 1;\n"
@@ -115,7 +122,8 @@ jit_generate(opcode, "int8_t r = 16 + (opcode & 0x7);\n"
                case 0x1000: {
                        switch (opcode & 0xfc00) {
                                case 0x1800:  { // SUB -- Subtract without carry -- 0001 10rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd - vr;\n"
 "STATE(\"sub %s[%02x], %s[%02x] = %02x\\n\", avr_regname(d), vd, avr_regname(r), vr, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -131,7 +139,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
                                        const int skip = 1 + _avr_is_instruction_32_bits(avr, new_pc);
                                         {
                                                jit_generate_literal("const int skip = %d", skip);
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint16_t res = vd == vr;\n"
 "STATE(\"cpse %s[%02x], %s[%02x]\\t; Will%s skip\\n\", avr_regname(d), avr_data[d], avr_regname(r), avr_data[r], res ? \"\":\" not\");\n"
 "if (res) {\n"
@@ -142,7 +151,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
                                        } break;
                                }       break;
                                case 0x1400:  { // CP -- Compare -- 0001 01rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd - vr;\n"
 "STATE(\"cp %s[%02x], %s[%02x] = %02x\\n\", avr_regname(d), vd, avr_regname(r), vr, res);\n"
 "_sreg = _avr_flags_sub_zns(_sreg, res, vd, vr);\n"
@@ -150,7 +160,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                }       break;
                                case 0x1c00:  { // ADD -- Add with carry -- 0001 11rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd + vr + SREG_BIT(S_C);\n"
 "if (r == d) {\n"
 "STATE(\"rol %s[%02x] = %02x\\n\", avr_regname(d), avr_data[d], res);\n"
@@ -169,7 +180,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
                case 0x2000: {
                        switch (opcode & 0xfc00) {
                                case 0x2000:  { // AND -- Logical AND -- 0010 00rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd & vr;\n"
 "if (r == d) {\n"
 "STATE(\"tst %s[%02x]\\n\", avr_regname(d), avr_data[d]);\n"
@@ -182,7 +194,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                }       break;
                                case 0x2400:  { // EOR -- Logical Exclusive OR -- 0010 01rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd ^ vr;\n"
 "if (r==d) {\n"
 "STATE(\"clr %s[%02x]\\n\", avr_regname(d), avr_data[d]);\n"
@@ -195,7 +208,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                }       break;
                                case 0x2800:  { // OR -- Logical OR -- 0010 10rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint8_t res = vd | vr;\n"
 "STATE(\"or %s[%02x], %s[%02x] = %02x\\n\", avr_regname(d), vd, avr_regname(r), vr, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -204,7 +218,8 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
 );
                                }       break;
                                case 0x2c00:  { // MOV -- 0010 11rd dddd rrrr
-jit_generate(opcode, "get_d5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5_vr5(opcode);\n"
 "uint8_t res = vr;\n"
 "STATE(\"mov %s, %s[%02x] = %02x\\n\", avr_regname(d), avr_regname(r), vr, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -215,7 +230,8 @@ jit_generate(opcode, "get_d5_vr5(opcode);\n"
                }       break;
 
                case 0x3000:  { // CPI -- Compare Immediate -- 0011 kkkk hhhh kkkk
-jit_generate(opcode, "get_vh4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vh4_k8(opcode);\n"
 "uint8_t res = vh - k;\n"
 "STATE(\"cpi %s[%02x], 0x%02x\\n\", avr_regname(h), vh, k);\n"
 "_sreg = _avr_flags_sub_zns(_sreg, res, vh, k);\n"
@@ -224,7 +240,8 @@ jit_generate(opcode, "get_vh4_k8(opcode);\n"
                }       break;
 
                case 0x4000:  { // SBCI -- Subtract Immediate With Carry -- 0100 kkkk hhhh kkkk
-jit_generate(opcode, "get_vh4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vh4_k8(opcode);\n"
 "uint8_t res = vh - k - SREG_BIT(S_C);\n"
 "STATE(\"sbci %s[%02x], 0x%02x = %02x\\n\", avr_regname(h), vh, k, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, h, res);\n"
@@ -234,7 +251,8 @@ jit_generate(opcode, "get_vh4_k8(opcode);\n"
                }       break;
 
                case 0x5000:  { // SUBI -- Subtract Immediate -- 0101 kkkk hhhh kkkk
-jit_generate(opcode, "get_vh4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vh4_k8(opcode);\n"
 "uint8_t res = vh - k;\n"
 "STATE(\"subi %s[%02x], 0x%02x = %02x\\n\", avr_regname(h), vh, k, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, h, res);\n"
@@ -244,7 +262,8 @@ jit_generate(opcode, "get_vh4_k8(opcode);\n"
                }       break;
 
                case 0x6000:  { // ORI aka SBR -- Logical OR with Immediate -- 0110 kkkk hhhh kkkk
-jit_generate(opcode, "get_vh4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vh4_k8(opcode);\n"
 "uint8_t res = vh | k;\n"
 "STATE(\"ori %s[%02x], 0x%02x\\n\", avr_regname(h), vh, k);\n"
 "_sreg = _avr_set_r(avr, _sreg, h, res);\n"
@@ -254,7 +273,8 @@ jit_generate(opcode, "get_vh4_k8(opcode);\n"
                }       break;
 
                case 0x7000:  { // ANDI -- Logical AND with Immediate -- 0111 kkkk hhhh kkkk
-jit_generate(opcode, "get_vh4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vh4_k8(opcode);\n"
 "uint8_t res = vh & k;\n"
 "STATE(\"andi %s[%02x], 0x%02x\\n\", avr_regname(h), vh, k);\n"
 "_sreg = _avr_set_r(avr, _sreg, h, res);\n"
@@ -276,7 +296,8 @@ jit_generate(opcode, "get_vh4_k8(opcode);\n"
                        switch (opcode & 0xd008) {
                                case 0xa000:
                                case 0x8000:  { // LD (LDD) -- Load Indirect using Z -- 10q0 qqsd dddd yqqq
-jit_generate(opcode, "uint16_t v = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
+jit_generate(opcode, 0+F_OP,
+"uint16_t v = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
 "get_d5_q6(opcode);\n"
 "if (opcode & 0x0200) {\n"
 "STATE(\"st (Z+%d[%04x]), %s[%02x]\\n\", q, v+q, avr_regname(d), avr_data[d]);\n"
@@ -285,12 +306,13 @@ jit_generate(opcode, "uint16_t v = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
 "STATE(\"ld %s, (Z+%d[%04x])=[%02x]\\n\", avr_regname(d), q, v+q, avr_data[v+q]);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, _avr_get_ram(avr, v+q));\n"
 "}\n"
-"cycle += 1; // 2 cycles, 3 for tinyavr\n"
+"cycle += 1;\n"
 );
                                }       break;
                                case 0xa008:
                                case 0x8008:  { // LD (LDD) -- Load Indirect using Y -- 10q0 qqsd dddd yqqq
-jit_generate(opcode, "uint16_t v = avr_data[R_YL] | (avr_data[R_YH] << 8);\n"
+jit_generate(opcode, 0+F_OP,
+"uint16_t v = avr_data[R_YL] | (avr_data[R_YH] << 8);\n"
 "get_d5_q6(opcode);\n"
 "if (opcode & 0x0200) {\n"
 "STATE(\"st (Y+%d[%04x]), %s[%02x]\\n\", q, v+q, avr_regname(d), avr_data[d]);\n"
@@ -299,7 +321,7 @@ jit_generate(opcode, "uint16_t v = avr_data[R_YL] | (avr_data[R_YH] << 8);\n"
 "STATE(\"ld %s, (Y+%d[%04x])=[%02x]\\n\", avr_regname(d), q, v+q, avr_data[d+q]);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, _avr_get_ram(avr, v+q));\n"
 "}\n"
-"cycle += 1; // 2 cycles, 3 for tinyavr\n"
+"cycle += 1;\n"
 );
                                }       break;
                                default: _avr_invalid_opcode(avr);
@@ -310,7 +332,8 @@ jit_generate(opcode, "uint16_t v = avr_data[R_YL] | (avr_data[R_YH] << 8);\n"
                        /* this is an annoying special case, but at least these lines handle all the SREG set/clear opcodes */
                        if ((opcode & 0xff0f) == 0x9408) {
                                 {
-jit_generate(opcode, "get_sreg_bit(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_sreg_bit(opcode);\n"
 "STATE(\"%s%c\\n\", opcode & 0x0080 ? \"cl\" : \"se\", _sreg_bit_name[b]);\n"
 "SREG_SETBIT(b, (opcode & 0x0080) == 0);\n"
 "SREG();\n"
@@ -318,7 +341,8 @@ jit_generate(opcode, "get_sreg_bit(opcode);\n"
                                } break;
                        } else switch (opcode) {
                                case 0x9588:  { // SLEEP -- 1001 0101 1000 1000
-jit_generate(opcode, "STATE(\"sleep\\n\");\n"
+jit_generate(opcode, 0,
+"STATE(\"sleep\\n\");\n"
 "/* Don't sleep if there are interrupts about to be serviced.\n"
 "* Without this check, it was possible to incorrectly enter a state\n"
 "* in which the cpu was sleeping and interrupts were disabled. For more\n"
@@ -330,11 +354,12 @@ jit_generate(opcode, "STATE(\"sleep\\n\");\n"
 );
                                }       break;
                                case 0x9598:  { // BREAK -- 1001 0101 1001 1000
-jit_generate(opcode, "STATE(\"break\\n\");\n"
+jit_generate(opcode, 0+F_NO_PC,
+"STATE(\"break\\n\");\n"
 "if (avr->gdb) {\n"
-"// if gdb is on, we break here as in here\n"
-"// and we do so until gdb restores the instruction\n"
-"// that was here before\n"
+"\n"
+"\n"
+"\n"
 "avr_state = cpu_StepDone;\n"
 "new_pc = avr->pc;\n"
 "cycle = 0;\n"
@@ -342,12 +367,14 @@ jit_generate(opcode, "STATE(\"break\\n\");\n"
 );
                                }       break;
                                case 0x95a8:  { // WDR -- Watchdog Reset -- 1001 0101 1010 1000
-jit_generate(opcode, "STATE(\"wdr\\n\");\n"
+jit_generate(opcode, 0,
+"STATE(\"wdr\\n\");\n"
 "SREG_FLUSH(avr_ioctl(avr, AVR_IOCTL_WATCHDOG_RESET, 0));\n"
 );
                                }       break;
                                case 0x95e8:  { // SPM -- Store Program Memory -- 1001 0101 1110 1000
-jit_generate(opcode, "STATE(\"spm\\n\");\n"
+jit_generate(opcode, 0,
+"STATE(\"spm\\n\");\n"
 "SREG_FLUSH(avr_ioctl(avr, AVR_IOCTL_FLASH_SPM, 0));\n"
 );
                                }       break;
@@ -362,7 +389,8 @@ jit_generate(opcode, "STATE(\"spm\\n\");\n"
                                         {
                                                jit_generate_literal("const int e = %d", e);
                                                jit_generate_literal("const int p = %d", p);
-jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
+jit_generate(opcode, 0+F_JUMP+F_NO_PC,
+"uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
 "if (e)\n"
 "z |= avr_data[avr_eind] << 16;\n"
 "STATE(\"%si%s Z[%04x]\\n\", e?\"e\":\"\", p?\"call\":\"jmp\", z << 1);\n"
@@ -376,22 +404,24 @@ jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
                                }       break;
                                case 0x9508:            // RET -- Return -- 1001 0101 0000 1000
                                case 0x9518:  { // RETI -- Return from Interrupt -- 1001 0101 0001 1000
-jit_generate(opcode, "if (opcode == 0x9518) {\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"if (opcode == 0x9518) {\n"
 "SREG_FLUSH(\n"
 "avr_sreg_set(avr, S_I, 1);\n"
 "avr_interrupt_reti(avr) );\n"
 "}\n"
 "new_pc = _avr_pop_addr(avr);\n"
 "cycle += 1 + avr_address_size;\n"
-"STATE(\"ret%s\\n\", opcode & 0x10 ? \"i\" : \"\");\n"
+"STATE(\"ret%s [%04x]\\n\", opcode & 0x10 ? \"i\" : \"\", new_pc);\n"
 "TRACE_JUMP();\n"
 "STACK_FRAME_POP();\n"
 );
                                }       break;
                                case 0x95c8:  { // LPM -- Load Program Memory R0 <- (Z) -- 1001 0101 1100 1000
-jit_generate(opcode, "uint16_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
+jit_generate(opcode, 0,
+"uint16_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
 "STATE(\"lpm %s, (Z[%04x]) = %02x\\n\", avr_regname(0), z, avr_flash[z]);\n"
-"cycle += 2; // 3 cycles\n"
+"cycle += 2;\n"
 "_sreg = _avr_set_r(avr, _sreg, 0, avr_flash[z]);\n"
 );
                                }       break;
@@ -399,34 +429,37 @@ jit_generate(opcode, "uint16_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
                                        if (!avr_rampz)
                                                _avr_invalid_opcode(avr);
                                         {
-jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr_data[avr_rampz] << 16);\n"
+jit_generate(opcode, 0,
+"uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr_data[avr_rampz] << 16);\n"
 "STATE(\"elpm %s, (Z[%02x:%04x])\\n\", avr_regname(0), z >> 16, z & 0xffff);\n"
 "_sreg = _avr_set_r(avr, _sreg, 0, avr_flash[z]);\n"
-"cycle += 2; // 3 cycles\n"
+"cycle += 2;\n"
 );
                                        }       break;
                                }       break;
                                default:  {
                                        switch (opcode & 0xfe0f) {
                                                case 0x9000:  { // LDS -- Load Direct from Data Space, 32 bits -- 1001 0000 0000 0000
-jit_generate(opcode, "get_d5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5(opcode);\n"
 "uint16_t x = _avr_flash_read16le(avr, new_pc);\n"
 "new_pc += 2;\n"
 "STATE(\"lds %s[%02x], 0x%04x\\n\", avr_regname(d), avr_data[d], x);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, _avr_get_ram(avr, x));\n"
-"cycle++; // 2 cycles\n"
+"cycle++;\n"
 );
                                                }       break;
                                                case 0x9005:
                                                case 0x9004:  { // LPM -- Load Program Memory -- 1001 000d dddd 01oo
-jit_generate(opcode, "get_d5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5(opcode);\n"
 "uint16_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8);\n"
 "int op = opcode & 1;\n"
 "STATE(\"lpm %s, (Z[%04x]%s)\\n\", avr_regname(d), z, op ? \"+\" : \"\");\n"
 "_sreg = _avr_set_r(avr, _sreg, d, avr_flash[z]);\n"
 "if (op)\n"
 "_avr_set_r16le_hl( R_ZL, z + 1);\n"
-"cycle += 2; // 3 cycles\n"
+"cycle += 2;\n"
 );
                                                }       break;
                                                case 0x9006:
@@ -434,7 +467,8 @@ jit_generate(opcode, "get_d5(opcode);\n"
                                                        if (!avr_rampz)
                                                                _avr_invalid_opcode(avr);
                                                         {
-jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr_data[avr_rampz] << 16);\n"
+jit_generate(opcode, 0+F_OP,
+"uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr_data[avr_rampz] << 16);\n"
 "get_d5(opcode);\n"
 "int op = opcode & 1;\n"
 "STATE(\"elpm %s, (Z[%02x:%04x]%s)\\n\", avr_regname(d), z >> 16, z & 0xffff, op ? \"+\" : \"\");\n"
@@ -444,7 +478,7 @@ jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr
 "_sreg = _avr_set_r(avr, _sreg, avr_rampz, z >> 16);\n"
 "_avr_set_r16le_hl( R_ZL, z);\n"
 "}\n"
-"cycle += 2; // 3 cycles\n"
+"cycle += 2;\n"
 );
                                                        }       break;
                                                }       break;
@@ -459,11 +493,12 @@ jit_generate(opcode, "uint32_t z = avr_data[R_ZL] | (avr_data[R_ZH] << 8) | (avr
                                                case 0x900c:
                                                case 0x900d:
                                                case 0x900e:  { // LD -- Load Indirect from Data using X -- 1001 000d dddd 11oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_d5(opcode);\n"
 "uint16_t x = (avr_data[R_XH] << 8) | avr_data[R_XL];\n"
 "STATE(\"ld %s, %sX[%04x]%s\\n\", avr_regname(d), op == 2 ? \"--\" : \"\", x, op == 1 ? \"++\" : \"\");\n"
-"cycle++; // 2 cycles (1 for tinyavr, except with inc/dec 2)\n"
+"cycle++;\n"
 "if (op == 2) x--;\n"
 "uint8_t vd = _avr_get_ram(avr, x);\n"
 "if (op == 1) x++;\n"
@@ -474,11 +509,12 @@ jit_generate(opcode, "int op = opcode & 3;\n"
                                                case 0x920c:
                                                case 0x920d:
                                                case 0x920e:  { // ST -- Store Indirect Data Space X -- 1001 001d dddd 11oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_vd5(opcode);\n"
 "uint16_t x = (avr_data[R_XH] << 8) | avr_data[R_XL];\n"
 "STATE(\"st %sX[%04x]%s, %s[%02x] \\n\", op == 2 ? \"--\" : \"\", x, op == 1 ? \"++\" : \"\", avr_regname(d), vd);\n"
-"cycle++; // 2 cycles, except tinyavr\n"
+"cycle++;\n"
 "if (op == 2) x--;\n"
 "_sreg = _avr_set_ram(avr, _sreg, x, vd);\n"
 "if (op == 1) x++;\n"
@@ -487,11 +523,12 @@ jit_generate(opcode, "int op = opcode & 3;\n"
                                                }       break;
                                                case 0x9009:
                                                case 0x900a:  { // LD -- Load Indirect from Data using Y -- 1001 000d dddd 10oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_d5(opcode);\n"
 "uint16_t y = (avr_data[R_YH] << 8) | avr_data[R_YL];\n"
 "STATE(\"ld %s, %sY[%04x]%s\\n\", avr_regname(d), op == 2 ? \"--\" : \"\", y, op == 1 ? \"++\" : \"\");\n"
-"cycle++; // 2 cycles, except tinyavr\n"
+"cycle++;\n"
 "if (op == 2) y--;\n"
 "uint8_t vd = _avr_get_ram(avr, y);\n"
 "if (op == 1) y++;\n"
@@ -501,7 +538,8 @@ jit_generate(opcode, "int op = opcode & 3;\n"
                                                }       break;
                                                case 0x9209:
                                                case 0x920a:  { // ST -- Store Indirect Data Space Y -- 1001 001d dddd 10oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_vd5(opcode);\n"
 "uint16_t y = (avr_data[R_YH] << 8) | avr_data[R_YL];\n"
 "STATE(\"st %sY[%04x]%s, %s[%02x]\\n\", op == 2 ? \"--\" : \"\", y, op == 1 ? \"++\" : \"\", avr_regname(d), vd);\n"
@@ -513,7 +551,8 @@ jit_generate(opcode, "int op = opcode & 3;\n"
 );
                                                }       break;
                                                case 0x9200:  { // STS -- Store Direct to Data Space, 32 bits -- 1001 0010 0000 0000
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint16_t x = _avr_flash_read16le(avr, new_pc);\n"
 "new_pc += 2;\n"
 "STATE(\"sts 0x%04x, %s[%02x]\\n\", x, avr_regname(d), vd);\n"
@@ -523,11 +562,12 @@ jit_generate(opcode, "get_vd5(opcode);\n"
                                                }       break;
                                                case 0x9001:
                                                case 0x9002:  { // LD -- Load Indirect from Data using Z -- 1001 000d dddd 00oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_d5(opcode);\n"
 "uint16_t z = (avr_data[R_ZH] << 8) | avr_data[R_ZL];\n"
 "STATE(\"ld %s, %sZ[%04x]%s\\n\", avr_regname(d), op == 2 ? \"--\" : \"\", z, op == 1 ? \"++\" : \"\");\n"
-"cycle++;; // 2 cycles, except tinyavr\n"
+"cycle++;;\n"
 "if (op == 2) z--;\n"
 "uint8_t vd = _avr_get_ram(avr, z);\n"
 "if (op == 1) z++;\n"
@@ -537,11 +577,12 @@ jit_generate(opcode, "int op = opcode & 3;\n"
                                                }       break;
                                                case 0x9201:
                                                case 0x9202:  { // ST -- Store Indirect Data Space Z -- 1001 001d dddd 00oo
-jit_generate(opcode, "int op = opcode & 3;\n"
+jit_generate(opcode, 0+F_OP,
+"int op = opcode & 3;\n"
 "get_vd5(opcode);\n"
 "uint16_t z = (avr_data[R_ZH] << 8) | avr_data[R_ZL];\n"
 "STATE(\"st %sZ[%04x]%s, %s[%02x] \\n\", op == 2 ? \"--\" : \"\", z, op == 1 ? \"++\" : \"\", avr_regname(d), vd);\n"
-"cycle++; // 2 cycles, except tinyavr\n"
+"cycle++;\n"
 "if (op == 2) z--;\n"
 "_sreg = _avr_set_ram(avr, _sreg, z, vd);\n"
 "if (op == 1) z++;\n"
@@ -549,7 +590,8 @@ jit_generate(opcode, "int op = opcode & 3;\n"
 );
                                                }       break;
                                                case 0x900f:  { // POP -- 1001 000d dddd 1111
-jit_generate(opcode, "get_d5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5(opcode);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, _avr_pop8(avr));\n"
 "T(uint16_t sp = _avr_sp_get(avr);)\n"
 "STATE(\"pop %s (@%04x)[%02x]\\n\", avr_regname(d), sp, avr_data[sp]);\n"
@@ -557,7 +599,8 @@ jit_generate(opcode, "get_d5(opcode);\n"
 );
                                                }       break;
                                                case 0x920f:  { // PUSH -- 1001 001d dddd 1111
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "_avr_push8(avr, vd);\n"
 "T(uint16_t sp = _avr_sp_get(avr);)\n"
 "STATE(\"push %s[%02x] (@%04x)\\n\", avr_regname(d), vd, sp);\n"
@@ -565,7 +608,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9400:  { // COM -- One's Complement -- 1001 010d dddd 0000
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = 0xff - vd;\n"
 "STATE(\"com %s[%02x] = %02x\\n\", avr_regname(d), vd, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -575,7 +619,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9401:  { // NEG -- Two's Complement -- 1001 010d dddd 0001
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = 0x00 - vd;\n"
 "STATE(\"neg %s[%02x] = %02x\\n\", avr_regname(d), vd, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -587,14 +632,16 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9402:  { // SWAP -- Swap Nibbles -- 1001 010d dddd 0010
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = (vd >> 4) | (vd << 4) ;\n"
 "STATE(\"swap %s[%02x] = %02x\\n\", avr_regname(d), vd, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
 );
                                                }       break;
                                                case 0x9403:  { // INC -- Increment -- 1001 010d dddd 0011
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = vd + 1;\n"
 "STATE(\"inc %s[%02x] = %02x\\n\", avr_regname(d), vd, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -604,7 +651,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9405:  { // ASR -- Arithmetic Shift Right -- 1001 010d dddd 0101
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = (vd >> 1) | (vd & 0x80);\n"
 "STATE(\"asr %s[%02x]\\n\", avr_regname(d), vd);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -613,7 +661,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9406:  { // LSR -- Logical Shift Right -- 1001 010d dddd 0110
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = vd >> 1;\n"
 "STATE(\"lsr %s[%02x]\\n\", avr_regname(d), vd);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -623,7 +672,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x9407:  { // ROR -- Rotate Right -- 1001 010d dddd 0111
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = (SREG_BIT(S_C) ? 0x80 : 0) | vd >> 1;\n"
 "STATE(\"ror %s[%02x]\\n\", avr_regname(d), vd);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -632,7 +682,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
 );
                                                }       break;
                                                case 0x940a:  { // DEC -- Decrement -- 1001 010d dddd 1010
-jit_generate(opcode, "get_vd5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5(opcode);\n"
 "uint8_t res = vd - 1;\n"
 "STATE(\"dec %s[%02x] = %02x\\n\", avr_regname(d), vd, res);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, res);\n"
@@ -643,7 +694,8 @@ jit_generate(opcode, "get_vd5(opcode);\n"
                                                }       break;
                                                case 0x940c:
                                                case 0x940d:  { // JMP -- Long Call to sub, 32 bits -- 1001 010a aaaa 110a
-jit_generate(opcode, "avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);\n"
 "uint16_t x = _avr_flash_read16le(avr, new_pc);\n"
 "a = (a << 16) | x;\n"
 "STATE(\"jmp 0x%06x\\n\", a);\n"
@@ -654,7 +706,8 @@ jit_generate(opcode, "avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1
                                                }       break;
                                                case 0x940e:
                                                case 0x940f:  { // CALL -- Long Call to sub, 32 bits -- 1001 010a aaaa 111a
-jit_generate(opcode, "avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);\n"
 "uint16_t x = _avr_flash_read16le(avr, new_pc);\n"
 "a = (a << 16) | x;\n"
 "STATE(\"call 0x%06x\\n\", a);\n"
@@ -669,7 +722,8 @@ jit_generate(opcode, "avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1
                                                default: {
                                                        switch (opcode & 0xff00) {
                                                                case 0x9600:  { // ADIW -- Add Immediate to Word -- 1001 0110 KKpp KKKK
-jit_generate(opcode, "get_vp2_k6(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vp2_k6(opcode);\n"
 "uint16_t res = vp + k;\n"
 "STATE(\"adiw %s:%s[%04x], 0x%02x\\n\", avr_regname(p), avr_regname(p + 1), vp, k);\n"
 "_avr_set_r16le_hl( p, res);\n"
@@ -681,7 +735,8 @@ jit_generate(opcode, "get_vp2_k6(opcode);\n"
 );
                                                                }       break;
                                                                case 0x9700:  { // SBIW -- Subtract Immediate from Word -- 1001 0111 KKpp KKKK
-jit_generate(opcode, "get_vp2_k6(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vp2_k6(opcode);\n"
 "uint16_t res = vp - k;\n"
 "STATE(\"sbiw %s:%s[%04x], 0x%02x\\n\", avr_regname(p), avr_regname(p + 1), vp, k);\n"
 "_avr_set_r16le_hl( p, res);\n"
@@ -693,7 +748,8 @@ jit_generate(opcode, "get_vp2_k6(opcode);\n"
 );
                                                                }       break;
                                                                case 0x9800:  { // CBI -- Clear Bit in I/O Register -- 1001 1000 AAAA Abbb
-jit_generate(opcode, "get_io5_b3mask(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_io5_b3mask(opcode);\n"
 "uint8_t res = _avr_get_ram(avr, io) & ~mask;\n"
 "STATE(\"cbi %s[%04x], 0x%02x = %02x\\n\", avr_regname(io), avr_data[io], mask, res);\n"
 "_sreg = _avr_set_ram(avr, _sreg, io, res);\n"
@@ -704,7 +760,8 @@ jit_generate(opcode, "get_io5_b3mask(opcode);\n"
                                                                        const int skip = 1 + _avr_is_instruction_32_bits(avr, new_pc);
                                                                         {      // SBIC -- Skip if Bit in I/O Register is Cleared -- 1001 1001 AAAA Abbb
                                                                                jit_generate_literal("const int skip = %d", skip);
-jit_generate(opcode, "get_io5_b3mask(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP,
+"get_io5_b3mask(opcode);\n"
 "uint8_t res = _avr_get_ram(avr, io) & mask;\n"
 "STATE(\"sbic %s[%04x], 0x%02x\\t; Will%s branch\\n\", avr_regname(io), avr_data[io], mask, !res?\"\":\" not\");\n"
 "if (!res) {\n"
@@ -715,7 +772,8 @@ jit_generate(opcode, "get_io5_b3mask(opcode);\n"
                                                                        }       break;
                                                                }       break;
                                                                case 0x9a00:  { // SBI -- Set Bit in I/O Register -- 1001 1010 AAAA Abbb
-jit_generate(opcode, "get_io5_b3mask(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_io5_b3mask(opcode);\n"
 "uint8_t res = _avr_get_ram(avr, io) | mask;\n"
 "STATE(\"sbi %s[%04x], 0x%02x = %02x\\n\", avr_regname(io), avr_data[io], mask, res);\n"
 "_sreg = _avr_set_ram(avr, _sreg, io, res);\n"
@@ -726,7 +784,8 @@ jit_generate(opcode, "get_io5_b3mask(opcode);\n"
                                                                        const int skip = 1 + _avr_is_instruction_32_bits(avr, new_pc);
                                                                         {      // SBIS -- Skip if Bit in I/O Register is Set -- 1001 1011 AAAA Abbb
                                                                                jit_generate_literal("const int skip = %d", skip);
-jit_generate(opcode, "get_io5_b3mask(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP,
+"get_io5_b3mask(opcode);\n"
 "uint8_t res = _avr_get_ram(avr, io) & mask;\n"
 "STATE(\"sbis %s[%04x], 0x%02x\\t; Will%s branch\\n\", avr_regname(io), avr_data[io], mask, res?\"\":\" not\");\n"
 "if (res) {\n"
@@ -739,7 +798,8 @@ jit_generate(opcode, "get_io5_b3mask(opcode);\n"
                                                                default:
                                                                        switch (opcode & 0xfc00) {
                                                                                case 0x9c00:  { // MUL -- Multiply Unsigned -- 1001 11rd dddd rrrr
-jit_generate(opcode, "get_vd5_vr5(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_vr5(opcode);\n"
 "uint16_t res = vd * vr;\n"
 "STATE(\"mul %s[%02x], %s[%02x] = %04x\\n\", avr_regname(d), vd, avr_regname(r), vr, res);\n"
 "cycle++;\n"
@@ -761,13 +821,15 @@ jit_generate(opcode, "get_vd5_vr5(opcode);\n"
                case 0xb000: {
                        switch (opcode & 0xf800) {
                                case 0xb800:  { // OUT A,Rr -- 1011 1AAd dddd AAAA
-jit_generate(opcode, "get_d5_a6(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5_a6(opcode);\n"
 "STATE(\"out %s, %s[%02x]\\n\", avr_regname(A), avr_regname(d), avr_data[d]);\n"
 "_sreg = _avr_set_ram(avr, _sreg, A, avr_data[d]);\n"
 );
                                }       break;
                                case 0xb000:  { // IN Rd,A -- 1011 0AAd dddd AAAA
-jit_generate(opcode, "get_d5_a6(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_d5_a6(opcode);\n"
 "STATE(\"in %s, %s[%02x]\\n\", avr_regname(d), avr_regname(A), avr_data[A]);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, _avr_get_ram(avr, A));\n"
 );
@@ -777,7 +839,8 @@ jit_generate(opcode, "get_d5_a6(opcode);\n"
                }       break;
 
                case 0xc000:  { // RJMP -- 1100 kkkk kkkk kkkk
-jit_generate(opcode, "get_o12(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"get_o12(opcode);\n"
 "STATE(\"rjmp .%d [%04x]\\n\", o >> 1, new_pc + o);\n"
 "new_pc = (new_pc + o) % (avr_flashend + 1);\n"
 "cycle++;\n"
@@ -786,11 +849,12 @@ jit_generate(opcode, "get_o12(opcode);\n"
                }       break;
 
                case 0xd000:  { // RCALL -- 1101 kkkk kkkk kkkk
-jit_generate(opcode, "get_o12(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"get_o12(opcode);\n"
 "STATE(\"rcall .%d [%04x]\\n\", o >> 1, new_pc + o);\n"
 "cycle += _avr_push_addr(avr, new_pc);\n"
 "new_pc = (new_pc + o) % (avr_flashend + 1);\n"
-"// 'rcall .1' is used as a cheap \"push 16 bits of room on the stack\"\n"
+"\n"
 "if (o != 0) {\n"
 "TRACE_JUMP();\n"
 "STACK_FRAME_PUSH();\n"
@@ -799,7 +863,8 @@ jit_generate(opcode, "get_o12(opcode);\n"
                }       break;
 
                case 0xe000:  { // LDI Rd, K aka SER (LDI r, 0xff) -- 1110 kkkk dddd kkkk
-jit_generate(opcode, "get_h4_k8(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_h4_k8(opcode);\n"
 "STATE(\"ldi %s, 0x%02x\\n\", avr_regname(h), k);\n"
 "_sreg = _avr_set_r(avr, _sreg, h, k);\n"
 );
@@ -811,9 +876,10 @@ jit_generate(opcode, "get_h4_k8(opcode);\n"
                                case 0xf200:
                                case 0xf400:
                                case 0xf600:  { // BRXC/BRXS -- All the SREG branches -- 1111 0Boo oooo osss
-jit_generate(opcode, "int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset\n"
+jit_generate(opcode, 0+F_JUMP+F_OP+F_NO_PC,
+"int16_t o = ((int16_t)(opcode << 6)) >> 9;\n"
 "uint8_t s = opcode & 7;\n"
-"int set = (opcode & 0x0400) == 0;             // this bit means BRXC otherwise BRXS\n"
+"int set = (opcode & 0x0400) == 0;\n"
 "int branch = (SREG_BIT(s) && set) || (!SREG_BIT(s) && !set);\n"
 "#ifdef CONFIG_SIMAVR_TRACE\n"
 "if (brxc_names[set][s]) {\n"
@@ -823,7 +889,7 @@ jit_generate(opcode, "int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset\n"
 "}\n"
 "#endif\n"
 "if (branch) {\n"
-"cycle++; // 2 cycles if taken, 1 otherwise\n"
+"cycle++;\n"
 "new_pc = new_pc + (o << 1);\n"
 "TRACE_JUMP();\n"
 "}\n"
@@ -831,7 +897,8 @@ jit_generate(opcode, "int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset\n"
                                }       break;
                                case 0xf800:
                                case 0xf900:  { // BLD -- Bit Store from T into a Bit in Register -- 1111 100d dddd 0bbb
-jit_generate(opcode, "get_vd5_s3_mask(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_s3_mask(opcode);\n"
 "uint8_t v = (vd & ~mask) | (SREG_BIT(S_T) ? mask : 0);\n"
 "STATE(\"bld %s[%02x], 0x%02x = %02x\\n\", avr_regname(d), vd, mask, v);\n"
 "_sreg = _avr_set_r(avr, _sreg, d, v);\n"
@@ -839,7 +906,8 @@ jit_generate(opcode, "get_vd5_s3_mask(opcode);\n"
                                }       break;
                                case 0xfa00:
                                case 0xfb00:  { // BST -- Bit Store into T from bit in Register -- 1111 101d dddd 0bbb
-jit_generate(opcode, "get_vd5_s3(opcode);\n"
+jit_generate(opcode, 0+F_OP,
+"get_vd5_s3(opcode);\n"
 "STATE(\"bst %s[%02x], 0x%02x\\n\", avr_regname(d), vd, 1 << s);\n"
 "SREG_SETBIT(S_T, (vd >> s) & 1);\n"
 "SREG();\n"
@@ -850,7 +918,8 @@ jit_generate(opcode, "get_vd5_s3(opcode);\n"
                                        const int skip = 1 + _avr_is_instruction_32_bits(avr, new_pc);
                                         {      // SBRS/SBRC -- Skip if Bit in Register is Set/Clear -- 1111 11sd dddd 0bbb
                                                jit_generate_literal("const int skip = %d", skip);
-jit_generate(opcode, "get_vd5_s3_mask(opcode);\n"
+jit_generate(opcode, 0+F_JUMP+F_OP,
+"get_vd5_s3_mask(opcode);\n"
 "int set = (opcode & 0x0200) != 0;\n"
 "int branch = ((vd & mask) && set) || (!(vd & mask) && !set);\n"
 "STATE(\"%s %s[%02x], 0x%02x\\t; Will%s branch\\n\", set ? \"sbrs\" : \"sbrc\", avr_regname(d), vd, mask, branch ? \"\":\" not\");\n"