From 275fe8c94b7f19260c58104e6cf5b7fe1f17cece Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 21 Jul 2021 07:52:39 +0900 Subject: codegen.c: a new function `get_int_operand`. --- mrbgems/mruby-compiler/core/codegen.c | 61 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 3c9d12f9f..80673d918 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -562,6 +562,33 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) } } +static mrb_bool +get_int_operand(struct mrb_insn_data *data, int32_t *n) +{ + switch (data->insn) { + case OP_LOADI__1: + *n = -1; + return TRUE; + + case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: + case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: + *n = data->insn - OP_LOADI_0; + return TRUE; + + case OP_LOADI: + case OP_LOADI16: + *n = data->b; + return TRUE; + + case OP_LOADI32: + *n = (int32_t)((uint32_t)data->b<<16)+data->c; + return TRUE; + + default: + return FALSE; + } +} + static void gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) { @@ -572,31 +599,21 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) } else { struct mrb_insn_data data = mrb_last_insn(s); + int32_t n; - switch (data.insn) { - case OP_LOADI__1: - if (op == OP_ADD) op = OP_SUB; - else op = OP_ADD; - data.b = 1; - goto replace; - case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: - case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: - data.b = data.insn - OP_LOADI_0; - /* fall through */ - case OP_LOADI: - case OP_LOADI16: - replace: - s->pc = s->lastpc; - if (op == OP_ADD) { - genop_2(s, OP_ADDI, dst, data.b); - } - else { - genop_2(s, OP_SUBI, dst, data.b); - } - break; - default: + if (!get_int_operand(&data, &n)) { + /* not integer immediate */ goto normal; } + /* OP_ADDI/OP_SUBI takes upto 16bits */ + if (n > INT16_MAX) goto normal; + s->pc = s->lastpc; + if (op == OP_ADD) { + genop_2(s, OP_ADDI, dst, (uint16_t)n); + } + else { + genop_2(s, OP_SUBI, dst, (uint16_t)n); + } } } -- cgit v1.2.3