Skip to content

Instantly share code, notes, and snippets.

@timo
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timo/00aac0df68b1e0afaae1 to your computer and use it in GitHub Desktop.
Save timo/00aac0df68b1e0afaae1 to your computer and use it in GitHub Desktop.
diff --git a/3rdparty/dyncall b/3rdparty/dyncall
--- a/3rdparty/dyncall
+++ b/3rdparty/dyncall
@@ -1 +1 @@
-Subproject commit 5c4e85c290756b84eb55c9ed97f550555bcdc29d
+Subproject commit 5c4e85c290756b84eb55c9ed97f550555bcdc29d-dirty
diff --git a/lib/MAST/Ops.nqp b/lib/MAST/Ops.nqp
index ad457f2..0eb8ca5 100644
--- a/lib/MAST/Ops.nqp
+++ b/lib/MAST/Ops.nqp
@@ -628,7 +628,9 @@ BEGIN {
1503,
1506,
1509,
- 1512);
+ 1512,
+ 1515,
+ 1517);
MAST::Ops.WHO<@counts> := nqp::list_i(0,
2,
2,
@@ -1254,7 +1256,9 @@ BEGIN {
3,
3,
3,
- 3);
+ 3,
+ 2,
+ 2);
MAST::Ops.WHO<@values> := nqp::list_i(10,
8,
18,
@@ -2769,7 +2773,11 @@ BEGIN {
49,
65,
16,
- 57);
+ 57,
+ 34,
+ 16,
+ 34,
+ 24);
MAST::Ops.WHO<%codes> := nqp::hash('no_op', 0,
'const_i8', 1,
'const_i16', 2,
@@ -3395,7 +3403,9 @@ BEGIN {
'sp_p6obind_o', 622,
'sp_p6obind_i', 623,
'sp_p6obind_n', 624,
- 'sp_p6obind_s', 625);
+ 'sp_p6obind_s', 625,
+ 'const_i64_16', 626,
+ 'const_i64_32', 627);
MAST::Ops.WHO<@names> := nqp::list('no_op',
'const_i8',
'const_i16',
@@ -4021,5 +4031,7 @@ BEGIN {
'sp_p6obind_o',
'sp_p6obind_i',
'sp_p6obind_n',
- 'sp_p6obind_s');
+ 'sp_p6obind_s',
+ 'const_i64_16',
+ 'const_i64_32');
}
diff --git a/src/core/interp.c b/src/core/interp.c
index 2ea59dc..d1a5c00 100644
--- a/src/core/interp.c
+++ b/src/core/interp.c
@@ -4238,6 +4238,14 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
cur_op += 4;
goto NEXT;
}
+ OP(const_i64_16):
+ GET_REG(cur_op, 0).i64 = GET_I16(cur_op, 2);
+ cur_op += 4;
+ goto NEXT;
+ OP(const_i64_32):
+ GET_REG(cur_op, 0).i64 = GET_I32(cur_op, 2);
+ cur_op += 6;
+ goto NEXT;
OP(sp_log):
if (tc->cur_frame->spesh_log_idx >= 0) {
MVM_ASSIGN_REF(tc, &(tc->cur_frame->static_info->common.header),
diff --git a/src/core/oplabels.h b/src/core/oplabels.h
index 451b902..5cbe13d 100644
--- a/src/core/oplabels.h
+++ b/src/core/oplabels.h
@@ -627,8 +627,8 @@ static const void * const LABELS[] = {
&&OP_sp_p6obind_i,
&&OP_sp_p6obind_n,
&&OP_sp_p6obind_s,
- NULL,
- NULL,
+ &&OP_const_i64_16,
+ &&OP_const_i64_32,
NULL,
NULL,
NULL,
diff --git a/src/core/oplist b/src/core/oplist
index 10b8310..0d91e3b 100644
--- a/src/core/oplist
+++ b/src/core/oplist
@@ -634,6 +634,10 @@ asyncreadbytes w(obj) r(obj) r(obj) r(obj) r(obj)
getlexstatic_o w(obj) r(str) :pure
getlexperinvtype_o w(obj) r(str) :pure
+# populate a 64bit integer register with a smaller integer
+const_i64_16 w(int64) int16 :pure
+const_i64_32 w(int64) int32 :pure
+
# Spesh ops. Naming convention: start with sp_. Must all be marked .s, which
# is how the validator knows to exclude them.
diff --git a/src/core/ops.c b/src/core/ops.c
index f75d2f6..c86236d 100644
--- a/src/core/ops.c
+++ b/src/core/ops.c
@@ -5636,9 +5636,27 @@ static MVMOpInfo MVM_op_infos[] = {
0,
{ MVM_operand_read_reg | MVM_operand_obj, MVM_operand_int16, MVM_operand_read_reg | MVM_operand_str }
},
+ {
+ MVM_OP_const_i64_16,
+ "const_i64_16",
+ " ",
+ 2,
+ 1,
+ 0,
+ { MVM_operand_write_reg | MVM_operand_int64, MVM_operand_int16 }
+ },
+ {
+ MVM_OP_const_i64_32,
+ "const_i64_32",
+ " ",
+ 2,
+ 1,
+ 0,
+ { MVM_operand_write_reg | MVM_operand_int64, MVM_operand_int32 }
+ },
};
-static unsigned short MVM_op_counts = 626;
+static unsigned short MVM_op_counts = 628;
MVMOpInfo * MVM_op_get_op(unsigned short op) {
if (op >= MVM_op_counts)
diff --git a/src/core/ops.h b/src/core/ops.h
index 9efc805..757830b 100644
--- a/src/core/ops.h
+++ b/src/core/ops.h
@@ -627,6 +627,8 @@
#define MVM_OP_sp_p6obind_i 623
#define MVM_OP_sp_p6obind_n 624
#define MVM_OP_sp_p6obind_s 625
+#define MVM_OP_const_i64_16 626
+#define MVM_OP_const_i64_32 627
#define MVM_OP_EXT_BASE 1024
#define MVM_OP_EXT_CU_LIMIT 1024
diff --git a/src/mast/compiler.c b/src/mast/compiler.c
index 938c237..c9ee38b 100644
--- a/src/mast/compiler.c
+++ b/src/mast/compiler.c
@@ -556,6 +556,9 @@ unsigned short get_callsite_id(VM, WriterState *ws, MASTNode *flags) {
return (unsigned short)ws->num_callsites++;
}
+#define OVERRIDE_WITH_32 1
+#define OVERRIDE_WITH_16 2
+
/* Compiles an instruction (which may actaully be any of the
* nodes valid directly in a Frame's instruction list, which
* means labels are valid too). */
@@ -564,6 +567,7 @@ void compile_instruction(VM, WriterState *ws, MASTNode *node) {
MAST_Op *o = GET_Op(node);
MVMOpInfo *info;
int i;
+ unsigned char override_second_argument;
/* Look up opcode and get argument info. */
unsigned short op = o->op;
@@ -584,14 +588,49 @@ void compile_instruction(VM, WriterState *ws, MASTNode *node) {
ELEMS(vm, o->operands), info->num_operands);
}
+ /* If we're outputting a const_i64 instruction, we may want to */
+ /* turn it into a const_i64_32 or const_i64_16 instead if it fits */
+ if (op == MVM_OP_const_i64) {
+ /* Now we'll do a terrible thing */
+ MASTNode *operand = ATPOS(vm, o->operands, 1);
+ MAST_IVal *iv = GET_IVal(operand);
+ if ((MVMint16) iv->value == iv->value) {
+ override_second_argument = OVERRIDE_WITH_16;
+ } else if ((MVMint32) iv->value == iv->value) {
+ override_second_argument = OVERRIDE_WITH_32;
+ } else {
+ override_second_argument = 0;
+ }
+ }
+
/* Write opcode. */
ensure_space(vm, &ws->bytecode_seg, &ws->bytecode_alloc, ws->bytecode_pos, 2);
- write_int16(ws->bytecode_seg, ws->bytecode_pos, op);
+ if (override_second_argument == 0)
+ write_int16(ws->bytecode_seg, ws->bytecode_pos, op);
+ else if (override_second_argument == OVERRIDE_WITH_16)
+ write_int16(ws->bytecode_seg, ws->bytecode_pos, MVM_OP_const_i64_16);
+ else if (override_second_argument == OVERRIDE_WITH_32)
+ write_int16(ws->bytecode_seg, ws->bytecode_pos, MVM_OP_const_i64_32);
ws->bytecode_pos += 2;
/* Write operands. */
- for (i = 0; i < info->num_operands; i++)
- compile_operand(vm, ws, info->operands[i], ATPOS(vm, o->operands, i));
+ for (i = 0; i < info->num_operands; i++) {
+ if (i == 1 && override_second_argument) {
+ MASTNode *operand = ATPOS(vm, o->operands, 1);
+ MAST_IVal *iv = GET_IVal(operand);
+ if (override_second_argument == OVERRIDE_WITH_32) {
+ ensure_space(vm, &ws->bytecode_seg, &ws->bytecode_alloc, ws->bytecode_pos, 4);
+ write_int32(ws->bytecode_seg, ws->bytecode_pos, (MVMint32)iv->value);
+ ws->bytecode_pos += 4;
+ } else {
+ ensure_space(vm, &ws->bytecode_seg, &ws->bytecode_alloc, ws->bytecode_pos, 2);
+ write_int16(ws->bytecode_seg, ws->bytecode_pos, (MVMint16)iv->value);
+ ws->bytecode_pos += 2;
+ }
+ } else {
+ compile_operand(vm, ws, info->operands[i], ATPOS(vm, o->operands, i));
+ }
+ }
}
else if (ISTYPE(vm, node, ws->types->ExtOp)) {
MAST_ExtOp *o = GET_ExtOp(node);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment