From 778ca94656d461e0880428151408d199c977afd2 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 3 Mar 2023 16:00:56 -0800 Subject: [PATCH 1/3] Use DECREF_INPUTS() more Also convert END_FOR (the only macro inst) to a regular inst. --- Python/bytecodes.c | 94 ++++++++++++++++---------------------- Python/generated_cases.c.h | 34 +++++--------- Python/opcode_metadata.h | 6 +-- 3 files changed, 53 insertions(+), 81 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index a715bfd3289ec9..1c3baef7c5b17f 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -135,7 +135,9 @@ dummy_func( res = NULL; } - macro(END_FOR) = POP_TOP + POP_TOP; + inst(END_FOR, (second, first --)) { + DECREF_INPUTS(); + } inst(UNARY_NEGATIVE, (value -- res)) { res = PyNumber_Negative(value); @@ -384,8 +386,7 @@ dummy_func( if (!_PyErr_Occurred(tstate)) { _PyErr_SetKeyError(sub); } - Py_DECREF(dict); - Py_DECREF(sub); + DECREF_INPUTS(); ERROR_IF(true, error); } Py_INCREF(res); // Do this before DECREF'ing dict, sub @@ -420,7 +421,7 @@ dummy_func( inst(SET_ADD, (set, unused[oparg-1], v -- set, unused[oparg-1])) { int err = PySet_Add(set, v); - Py_DECREF(v); + DECREF_INPUTS(); ERROR_IF(err, error); PREDICT(JUMP_BACKWARD); } @@ -899,7 +900,7 @@ dummy_func( #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; int res = unpack_iterable(tstate, seq, oparg, -1, top); - Py_DECREF(seq); + DECREF_INPUTS(); ERROR_IF(res == 0, error); } @@ -910,7 +911,7 @@ dummy_func( STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); - Py_DECREF(seq); + DECREF_INPUTS(); } inst(UNPACK_SEQUENCE_TUPLE, (unused/1, seq -- values[oparg])) { @@ -921,7 +922,7 @@ dummy_func( for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - Py_DECREF(seq); + DECREF_INPUTS(); } inst(UNPACK_SEQUENCE_LIST, (unused/1, seq -- values[oparg])) { @@ -932,14 +933,14 @@ dummy_func( for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - Py_DECREF(seq); + DECREF_INPUTS(); } inst(UNPACK_EX, (seq -- unused[oparg & 0xFF], unused, unused[oparg >> 8])) { int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); - Py_DECREF(seq); + DECREF_INPUTS(); ERROR_IF(res == 0, error); } @@ -967,22 +968,21 @@ dummy_func( #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, v); - Py_DECREF(v); - Py_DECREF(owner); + DECREF_INPUTS(); ERROR_IF(err, error); } inst(DELETE_ATTR, (owner --)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - Py_DECREF(owner); + DECREF_INPUTS(); ERROR_IF(err, error); } inst(STORE_GLOBAL, (v --)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); - Py_DECREF(v); + DECREF_INPUTS(); ERROR_IF(err, error); } @@ -1249,9 +1249,7 @@ dummy_func( inst(BUILD_STRING, (pieces[oparg] -- str)) { str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - for (int i = 0; i < oparg; i++) { - Py_DECREF(pieces[i]); - } + DECREF_INPUTS(); ERROR_IF(str == NULL, error); } @@ -1314,10 +1312,7 @@ dummy_func( if (map == NULL) goto error; - for (int i = 0; i < oparg; i++) { - Py_DECREF(values[i*2]); - Py_DECREF(values[i*2+1]); - } + DECREF_INPUTS(); ERROR_IF(map == NULL, error); } @@ -1373,10 +1368,7 @@ dummy_func( map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - Py_DECREF(keys); - for (int i = 0; i < oparg; i++) { - Py_DECREF(values[i]); - } + DECREF_INPUTS(); ERROR_IF(map == NULL, error); } @@ -1464,7 +1456,7 @@ dummy_func( NULL | meth | arg1 | ... | argN */ - Py_DECREF(owner); + DECREF_INPUTS(); ERROR_IF(meth == NULL, error); res2 = NULL; res = meth; @@ -1473,7 +1465,7 @@ dummy_func( else { /* Classic, pushes one value. */ res = PyObject_GetAttr(owner, name); - Py_DECREF(owner); + DECREF_INPUTS(); ERROR_IF(res == NULL, error); } } @@ -1492,7 +1484,7 @@ dummy_func( STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - Py_DECREF(owner); + DECREF_INPUTS(); } inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { @@ -1509,7 +1501,7 @@ dummy_func( STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - Py_DECREF(owner); + DECREF_INPUTS(); } inst(LOAD_ATTR_WITH_HINT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { @@ -1540,7 +1532,7 @@ dummy_func( STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - Py_DECREF(owner); + DECREF_INPUTS(); } inst(LOAD_ATTR_SLOT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { @@ -1554,7 +1546,7 @@ dummy_func( STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - Py_DECREF(owner); + DECREF_INPUTS(); } inst(LOAD_ATTR_CLASS, (unused/1, type_version/2, unused/2, descr/4, cls -- res2 if (oparg & 1), res)) { @@ -1570,7 +1562,7 @@ dummy_func( res = descr; assert(res != NULL); Py_INCREF(res); - Py_DECREF(cls); + DECREF_INPUTS(); } inst(LOAD_ATTR_PROPERTY, (unused/1, type_version/2, func_version/2, fget/4, owner -- unused if (oparg & 1), unused)) { @@ -1707,8 +1699,7 @@ dummy_func( STAT_INC(COMPARE_OP, deferred); assert((oparg >> 4) <= Py_GE); res = PyObject_RichCompare(left, right, oparg>>4); - Py_DECREF(left); - Py_DECREF(right); + DECREF_INPUTS(); ERROR_IF(res == NULL, error); } @@ -1734,8 +1725,7 @@ dummy_func( #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 4) <= Py_GE); PyObject *cond = PyObject_RichCompare(left, right, oparg>>4); - Py_DECREF(left); - Py_DECREF(right); + DECREF_INPUTS(); ERROR_IF(cond == NULL, error); assert(next_instr[1].op.code == POP_JUMP_IF_FALSE || next_instr[1].op.code == POP_JUMP_IF_TRUE); @@ -1885,7 +1875,7 @@ dummy_func( } else { int err = PyObject_IsTrue(cond); - Py_DECREF(cond); + DECREF_INPUTS(); if (err == 0) { JUMPBY(oparg); } @@ -1905,7 +1895,7 @@ dummy_func( } else { int err = PyObject_IsTrue(cond); - Py_DECREF(cond); + DECREF_INPUTS(); if (err > 0) { JUMPBY(oparg); } @@ -1917,7 +1907,7 @@ dummy_func( inst(POP_JUMP_IF_NOT_NONE, (value -- )) { if (!Py_IsNone(value)) { - Py_DECREF(value); + DECREF_INPUTS(); JUMPBY(oparg); } else { @@ -1931,7 +1921,7 @@ dummy_func( JUMPBY(oparg); } else { - Py_DECREF(value); + DECREF_INPUTS(); } } @@ -1948,7 +1938,7 @@ dummy_func( else { err = PyObject_IsTrue(cond); if (err > 0) { - Py_DECREF(cond); + DECREF_INPUTS(); } else if (err == 0) { JUMPBY(oparg); @@ -1977,7 +1967,7 @@ dummy_func( jump = true; } else if (err == 0) { - Py_DECREF(cond); + DECREF_INPUTS(); } else { goto error; @@ -2065,7 +2055,7 @@ dummy_func( if (iter == NULL) { goto error; } - Py_DECREF(iterable); + DECREF_INPUTS(); } PREDICT(LOAD_CONST); } @@ -2110,7 +2100,7 @@ dummy_func( } /* iterator ended normally */ assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); - Py_DECREF(iter); + DECREF_INPUTS(); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2133,7 +2123,7 @@ dummy_func( it->it_seq = NULL; Py_DECREF(seq); } - Py_DECREF(iter); + DECREF_INPUTS(); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2156,7 +2146,7 @@ dummy_func( it->it_seq = NULL; Py_DECREF(seq); } - Py_DECREF(iter); + DECREF_INPUTS(); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2940,9 +2930,7 @@ dummy_func( assert(PyTuple_CheckExact(callargs)); result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing); - Py_DECREF(func); - Py_DECREF(callargs); - Py_XDECREF(kwargs); + DECREF_INPUTS(); assert(PEEK(3 + (oparg & 1)) == NULL); ERROR_IF(result == NULL, error); @@ -3009,9 +2997,7 @@ dummy_func( inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) { slice = PySlice_New(start, stop, step); - Py_DECREF(start); - Py_DECREF(stop); - Py_XDECREF(step); + DECREF_INPUTS(); ERROR_IF(slice == NULL, error); } @@ -3057,8 +3043,7 @@ dummy_func( } else { /* Actually call format(). */ result = PyObject_Format(value, fmt_spec); - Py_DECREF(value); - Py_XDECREF(fmt_spec); + DECREF_INPUTS(); ERROR_IF(result == NULL, error); } } @@ -3084,8 +3069,7 @@ dummy_func( assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - Py_DECREF(lhs); - Py_DECREF(rhs); + DECREF_INPUTS(); ERROR_IF(res == NULL, error); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 631b7844f9ed88..7bd0b3826174c8 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -184,16 +184,10 @@ } TARGET(END_FOR) { - PyObject *_tmp_1 = stack_pointer[-1]; - PyObject *_tmp_2 = stack_pointer[-2]; - { - PyObject *value = _tmp_1; - Py_DECREF(value); - } - { - PyObject *value = _tmp_2; - Py_DECREF(value); - } + PyObject *first = stack_pointer[-1]; + PyObject *second = stack_pointer[-2]; + Py_DECREF(second); + Py_DECREF(first); STACK_SHRINK(2); DISPATCH(); } @@ -1568,8 +1562,8 @@ PyObject **pieces = (stack_pointer - oparg); PyObject *str; str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - for (int i = 0; i < oparg; i++) { - Py_DECREF(pieces[i]); + for (int _i = oparg; --_i >= 0;) { + Py_DECREF(pieces[_i]); } if (str == NULL) { STACK_SHRINK(oparg); goto error; } STACK_SHRINK(oparg); @@ -1665,9 +1659,8 @@ if (map == NULL) goto error; - for (int i = 0; i < oparg; i++) { - Py_DECREF(values[i*2]); - Py_DECREF(values[i*2+1]); + for (int _i = oparg*2; --_i >= 0;) { + Py_DECREF(values[_i]); } if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } STACK_SHRINK(oparg*2); @@ -1732,10 +1725,10 @@ map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - Py_DECREF(keys); - for (int i = 0; i < oparg; i++) { - Py_DECREF(values[i]); + for (int _i = oparg; --_i >= 0;) { + Py_DECREF(values[_i]); } + Py_DECREF(keys); if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } STACK_SHRINK(oparg); stack_pointer[-1] = map; @@ -2470,7 +2463,6 @@ else { err = PyObject_IsTrue(cond); if (err > 0) { - Py_DECREF(cond); } else if (err == 0) { JUMPBY(oparg); @@ -2503,7 +2495,6 @@ jump = true; } else if (err == 0) { - Py_DECREF(cond); } else { goto error; @@ -2668,7 +2659,6 @@ } /* iterator ended normally */ assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); - Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2697,7 +2687,6 @@ it->it_seq = NULL; Py_DECREF(seq); } - Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2726,7 +2715,6 @@ it->it_seq = NULL; Py_DECREF(seq); } - Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 93f3c76c5b8240..c2db59d6201539 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -38,7 +38,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case PUSH_NULL: return 0; case END_FOR: - return 1+1; + return 2; case UNARY_NEGATIVE: return 1; case UNARY_NOT: @@ -390,7 +390,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case PUSH_NULL: return 1; case END_FOR: - return 0+0; + return 0; case UNARY_NEGATIVE: return 1; case UNARY_NOT: @@ -735,7 +735,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = { [LOAD_CONST__LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, [POP_TOP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [PUSH_NULL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, - [END_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [END_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [UNARY_NEGATIVE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [UNARY_NOT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [UNARY_INVERT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, From 68077f1ae7c6ac20d8bd6585f07756f40a162d7a Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 4 Mar 2023 10:29:24 -0800 Subject: [PATCH 2/3] Whoops, cannot use DECREF_INPUTS() in some cases --- Python/bytecodes.c | 10 +++++----- Python/generated_cases.c.h | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 1c3baef7c5b17f..258bcb93a19dbc 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1938,7 +1938,7 @@ dummy_func( else { err = PyObject_IsTrue(cond); if (err > 0) { - DECREF_INPUTS(); + Py_DECREF(cond); } else if (err == 0) { JUMPBY(oparg); @@ -1967,7 +1967,7 @@ dummy_func( jump = true; } else if (err == 0) { - DECREF_INPUTS(); + Py_DECREF(cond); } else { goto error; @@ -2100,7 +2100,7 @@ dummy_func( } /* iterator ended normally */ assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); - DECREF_INPUTS(); + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2123,7 +2123,7 @@ dummy_func( it->it_seq = NULL; Py_DECREF(seq); } - DECREF_INPUTS(); + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2146,7 +2146,7 @@ dummy_func( it->it_seq = NULL; Py_DECREF(seq); } - DECREF_INPUTS(); + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7bd0b3826174c8..a64b930c8b9e3e 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2463,6 +2463,7 @@ else { err = PyObject_IsTrue(cond); if (err > 0) { + Py_DECREF(cond); } else if (err == 0) { JUMPBY(oparg); @@ -2495,6 +2496,7 @@ jump = true; } else if (err == 0) { + Py_DECREF(cond); } else { goto error; @@ -2659,6 +2661,7 @@ } /* iterator ended normally */ assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2687,6 +2690,7 @@ it->it_seq = NULL; Py_DECREF(seq); } + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); @@ -2715,6 +2719,7 @@ it->it_seq = NULL; Py_DECREF(seq); } + Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); From 12e85cfc6a114d40d04528c6305efb78652ef12c Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 13 Mar 2023 13:20:32 -0700 Subject: [PATCH 3/3] Don't mess with END_FOR --- Python/bytecodes.c | 4 +--- Python/generated_cases.c.h | 14 ++++++++++---- Python/opcode_metadata.h | 6 +++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 258bcb93a19dbc..74582ecbbda103 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -135,9 +135,7 @@ dummy_func( res = NULL; } - inst(END_FOR, (second, first --)) { - DECREF_INPUTS(); - } + macro(END_FOR) = POP_TOP + POP_TOP; inst(UNARY_NEGATIVE, (value -- res)) { res = PyNumber_Negative(value); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a64b930c8b9e3e..b1dbb58d956367 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -184,10 +184,16 @@ } TARGET(END_FOR) { - PyObject *first = stack_pointer[-1]; - PyObject *second = stack_pointer[-2]; - Py_DECREF(second); - Py_DECREF(first); + PyObject *_tmp_1 = stack_pointer[-1]; + PyObject *_tmp_2 = stack_pointer[-2]; + { + PyObject *value = _tmp_1; + Py_DECREF(value); + } + { + PyObject *value = _tmp_2; + Py_DECREF(value); + } STACK_SHRINK(2); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index c2db59d6201539..93f3c76c5b8240 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -38,7 +38,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case PUSH_NULL: return 0; case END_FOR: - return 2; + return 1+1; case UNARY_NEGATIVE: return 1; case UNARY_NOT: @@ -390,7 +390,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case PUSH_NULL: return 1; case END_FOR: - return 0; + return 0+0; case UNARY_NEGATIVE: return 1; case UNARY_NOT: @@ -735,7 +735,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = { [LOAD_CONST__LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, [POP_TOP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [PUSH_NULL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, - [END_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [END_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [UNARY_NEGATIVE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [UNARY_NOT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [UNARY_INVERT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },