Add a new instruction `OP_LOADI32`.
That loads 32 bit integer bypassing pool access.
MODIFY
include/mruby/opcode.h
include/mruby/opcode.h
@@ -36,6 +36,7 @@ enum mrb_insn {
#define FETCH_BB() do {a=READ_B(); b=READ_B();} while (0)
#define FETCH_BBB() do {a=READ_B(); b=READ_B(); c=READ_B();} while (0)
#define FETCH_BS() do {a=READ_B(); b=READ_S();} while (0)
+#define FETCH_BSS() do {a=READ_B(); b=READ_S(); c=READ_S();} while (0)
#define FETCH_S() do {a=READ_S();} while (0)
#define FETCH_W() do {a=READ_W();} while (0)

MODIFY
include/mruby/ops.h
include/mruby/ops.h
/* operand types:
- + Z: no operand (Z,Z,Z,Z)
- + B: 8bit (B,S,B,B)
- + BB: 8+8bit (BB,SB,BS,SS)
- + BBB: 8+8+8bit (BBB,SBB,BSB,SSB)
- + BS: 8+16bit (BS,SS,BS,BS)
- + S: 16bit (S,S,S,S)
- + W: 24bit (W,W,W,W)
+ + Z: no operand
+ + B: 8bit
+ + BB: 8+8bit
+ + BBB: 8+8+8bit
+ + BS: 8+16bit
+ + BSS: 8+16+16bit
+ + S: 16bit
+ + W: 24bit
*/
/*-----------------------------------------------------------------------
@@ -27,6 +28,7 @@ OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */
OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */
OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
+OPCODE(LOADI32, BSS) /* R(a) = mrb_int((b<<16)+c) */
OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */
OPCODE(LOADSYM16, BS) /* R(a) = Syms(b) */
OPCODE(LOADNIL, B) /* R(a) = nil */

MODIFY
mrbgems/mruby-compiler/core/codegen.c
mrbgems/mruby-compiler/core/codegen.c
@@ -283,6 +283,14 @@ genop_2S(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
gen_S(s, b);
}
+static void
+genop_2SS(codegen_scope *s, mrb_code i, uint16_t a, uint32_t b)
+{
+ genop_1(s, i, a);
+ gen_S(s, b>>16);
+ gen_S(s, b&0xffff);
+}
+
static void
genop_W(codegen_scope *s, mrb_code i, uint32_t a)
{
@@ -315,7 +323,7 @@ mrb_decode_insn(const mrb_code *pc)
mrb_code insn = READ_B();
uint16_t a = 0;
uint16_t b = 0;
- uint8_t c = 0;
+ uint16_t c = 0;
switch (insn) {
#define FETCH_Z() /* empty */
@@ -2479,11 +2487,13 @@ codegen(codegen_scope *s, node *tree, int val)
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 if (i >= -0x80000000) genop_2SS(s, OP_LOADI32, cursp(), (uint32_t)i);
else goto lit_int;
}
else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp());
else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
else if (i <= 0x7fff) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
+ else if (i <= 0x7fffffff) genop_2SS(s, OP_LOADI32, cursp(), (uint32_t)i);
else {
int off;
@@ -2550,6 +2560,9 @@ codegen(codegen_scope *s, node *tree, int val)
else if (i >= -0x8000) {
genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
}
+ else if (i >= -0x80000000) {
+ genop_2S(s, OP_LOADI32, cursp(), (uint32_t)i);
+ }
else {
int off = new_lit(s, mrb_int_value(s->mrb, i));
genop_bs(s, OP_LOADL, cursp(), off);
@@ -3301,6 +3314,7 @@ uint8_t mrb_insn_size[] = {
#define BB 3
#define BBB 4
#define BS 4
+#define BSS 6
#define SB 4
#define OPCODE(_,x) x,
#include "mruby/ops.h"
@@ -3308,6 +3322,7 @@ uint8_t mrb_insn_size[] = {
#undef B
#undef BB
#undef BS
+#undef BSS
#undef SB
#undef BBB
};

MODIFY
src/codedump.c
src/codedump.c
@@ -115,7 +115,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
ptrdiff_t i;
uint32_t a;
uint16_t b;
- uint8_t c;
+ uint16_t c;
ai = mrb_gc_arena_save(mrb);
@@ -169,6 +169,10 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b);
print_lv_a(mrb, irep, a);
break;
+ CASE(OP_LOADI32, BSS);
+ printf("OP_LOADI32\tR%d\t%d\t", a, (int)(b<<16)+c);
+ 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);

MODIFY
src/vm.c
src/vm.c
@@ -1030,7 +1030,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
struct mrb_jmpbuf c_jmp;
uint32_t a;
uint16_t b;
- uint8_t c;
+ uint16_t c;
mrb_sym mid;
const struct mrb_irep_catch_handler *ch;
@@ -1138,6 +1138,11 @@ RETRY_TRY_BLOCK:
NEXT;
}
+ CASE(OP_LOADI32, BSS) {
+ SET_INT_VALUE(mrb, regs[a], (mrb_int)(b<<16)+c);
+ NEXT;
+ }
+
CASE(OP_LOADSYM, BB) {
SET_SYM_VALUE(regs[a], syms[b]);
NEXT;

Add a new instruction `OP_LOADI32`.

That loads 32 bit integer bypassing pool access.