From fa8668c77d181a5075dc56fb63d6fa087ab4b1d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 17 Jan 2020 09:28:21 +0900 Subject: Add a new instruction `OP_LOADI16`. Which loads 16bit integer to the register. The instruction number should be reorder on massive instruction refactoring. The instruction is added for `mruby/c` which had performance issue with `OP_EXT`. With this instruction, `mruby/c` VM can just raise errors on `OP_EXT` extension instructions. --- include/mruby/ops.h | 1 + mrbgems/mruby-compiler/core/codegen.c | 21 ++++++++++++++++----- src/codedump.c | 4 ++++ src/vm.c | 5 +++++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 2327c33fd..c8990ae43 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -115,3 +115,4 @@ OPCODE(EXT1, Z) /* make 1st operand 16bit */ OPCODE(EXT2, Z) /* make 2nd operand 16bit */ OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */ OPCODE(STOP, Z) /* stop VM */ +OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 717d9eb9a..162666eb9 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2440,12 +2440,20 @@ codegen(codegen_scope *s, node *tree, int val) else #endif { - if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); + if (i < 0) { + if (i == -1) genop_1(s, OP_LOADI__1, cursp()); + else if (i >= -0xff) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); + else if (i >= -0x8000) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); + else goto lit_int; + } else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp()); - else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); + else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); + else if (i <= 0xffff) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); else { - int off = new_lit(s, mrb_fixnum_value(i)); + int off; + + lit_int: + off = new_lit(s, mrb_fixnum_value(i)); genop_2(s, OP_LOADL, cursp(), off); } } @@ -2501,9 +2509,12 @@ codegen(codegen_scope *s, node *tree, int val) else { #endif if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i >= -0xffff) { + else if (i >= -0xff) { genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); } + else if (i >= -0x8000) { + genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); + } else { int off = new_lit(s, mrb_fixnum_value(i)); genop_2(s, OP_LOADL, cursp(), off); diff --git a/src/codedump.c b/src/codedump.c index 7faa39360..649be176b 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -130,6 +130,10 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("OP_LOADI\tR%d\t-%d\t", a, b); print_lv_a(mrb, irep, a); break; + CASE(OP_LOADI16, BS): + printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); + print_lv_a(mrb, irep, a); + break; CASE(OP_LOADI__1, B): printf("OP_LOADI__1\tR%d\t\t", a); print_lv_a(mrb, irep, a); diff --git a/src/vm.c b/src/vm.c index ea1bb5087..26da5831e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1047,6 +1047,11 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_LOADI16, BS) { + SET_INT_VALUE(regs[a], (mrb_int)(int16_t)b); + NEXT; + } + CASE(OP_LOADSYM, BB) { SET_SYM_VALUE(regs[a], syms[b]); NEXT; -- cgit v1.2.3