From 8c6a53cdc28c2e88e686d4ec35ef4281ee28b2ca Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Thu, 21 Sep 2017 10:52:29 +0100 Subject: [PATCH] jit: Simplified generated code Removed unnecessary bits, like opcode if not needed. Also, strip comments. Fix 32 bits instructions too. Signed-off-by: Michel Pollet --- simavr/Makefile | 2 +- simavr/jit_emitter_generate.sh | 13 +- simavr/sim/sim_core.c | 2 +- simavr/sim/sim_core_jit.c | 51 +++++-- simavr/sim/sim_core_jit.h | 253 +++++++++++++++++++++------------ 5 files changed, 214 insertions(+), 107 deletions(-) diff --git a/simavr/Makefile b/simavr/Makefile index 6b94cd9..2d1df80 100644 --- a/simavr/Makefile +++ b/simavr/Makefile @@ -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 diff --git a/simavr/jit_emitter_generate.sh b/simavr/jit_emitter_generate.sh index 46cc564..5bee9af 100755 --- a/simavr/jit_emitter_generate.sh +++ b/simavr/jit_emitter_generate.sh @@ -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"; } diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c index 197fbc9..23ba093 100644 --- a/simavr/sim/sim_core.c +++ b/simavr/sim/sim_core.c @@ -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; diff --git a/simavr/sim/sim_core_jit.c b/simavr/sim/sim_core_jit.c index dcf2ef4..ac5d0fb 100644 --- a/simavr/sim/sim_core_jit.c +++ b/simavr/sim/sim_core_jit.c @@ -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; diff --git a/simavr/sim/sim_core_jit.h b/simavr/sim/sim_core_jit.h index 6cfb341..80d4fe9 100644 --- a/simavr/sim/sim_core_jit.h +++ b/simavr/sim/sim_core_jit.h @@ -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" -- 2.39.5