PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
+PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
_PyBytes_DecodeEscape(), etc. */
#define BINARY_OP_INPLACE_ADD_UNICODE 16
#define BINARY_OP_MULTIPLY_INT 17
#define BINARY_OP_MULTIPLY_FLOAT 18
-#define BINARY_SUBSCR_ADAPTIVE 19
-#define BINARY_SUBSCR_LIST_INT 20
-#define BINARY_SUBSCR_TUPLE_INT 21
-#define BINARY_SUBSCR_DICT 22
-#define CALL_FUNCTION_ADAPTIVE 23
-#define CALL_FUNCTION_BUILTIN_O 24
-#define CALL_FUNCTION_BUILTIN_FAST 26
-#define CALL_FUNCTION_LEN 27
-#define CALL_FUNCTION_ISINSTANCE 28
-#define CALL_FUNCTION_PY_SIMPLE 29
-#define JUMP_ABSOLUTE_QUICK 34
-#define LOAD_ATTR_ADAPTIVE 36
-#define LOAD_ATTR_INSTANCE_VALUE 38
-#define LOAD_ATTR_WITH_HINT 39
-#define LOAD_ATTR_SLOT 40
-#define LOAD_ATTR_MODULE 41
-#define LOAD_GLOBAL_ADAPTIVE 42
-#define LOAD_GLOBAL_MODULE 43
-#define LOAD_GLOBAL_BUILTIN 44
-#define LOAD_METHOD_ADAPTIVE 45
-#define LOAD_METHOD_CACHED 46
-#define LOAD_METHOD_CLASS 47
-#define LOAD_METHOD_MODULE 48
-#define LOAD_METHOD_NO_DICT 55
-#define STORE_ATTR_ADAPTIVE 56
-#define STORE_ATTR_INSTANCE_VALUE 57
-#define STORE_ATTR_SLOT 58
-#define STORE_ATTR_WITH_HINT 59
-#define LOAD_FAST__LOAD_FAST 62
-#define STORE_FAST__LOAD_FAST 63
-#define LOAD_FAST__LOAD_CONST 64
-#define LOAD_CONST__LOAD_FAST 65
-#define STORE_FAST__STORE_FAST 66
+#define BINARY_OP_SUBTRACT_INT 19
+#define BINARY_OP_SUBTRACT_FLOAT 20
+#define BINARY_SUBSCR_ADAPTIVE 21
+#define BINARY_SUBSCR_LIST_INT 22
+#define BINARY_SUBSCR_TUPLE_INT 23
+#define BINARY_SUBSCR_DICT 24
+#define CALL_FUNCTION_ADAPTIVE 26
+#define CALL_FUNCTION_BUILTIN_O 27
+#define CALL_FUNCTION_BUILTIN_FAST 28
+#define CALL_FUNCTION_LEN 29
+#define CALL_FUNCTION_ISINSTANCE 34
+#define CALL_FUNCTION_PY_SIMPLE 36
+#define JUMP_ABSOLUTE_QUICK 38
+#define LOAD_ATTR_ADAPTIVE 39
+#define LOAD_ATTR_INSTANCE_VALUE 40
+#define LOAD_ATTR_WITH_HINT 41
+#define LOAD_ATTR_SLOT 42
+#define LOAD_ATTR_MODULE 43
+#define LOAD_GLOBAL_ADAPTIVE 44
+#define LOAD_GLOBAL_MODULE 45
+#define LOAD_GLOBAL_BUILTIN 46
+#define LOAD_METHOD_ADAPTIVE 47
+#define LOAD_METHOD_CACHED 48
+#define LOAD_METHOD_CLASS 55
+#define LOAD_METHOD_MODULE 56
+#define LOAD_METHOD_NO_DICT 57
+#define STORE_ATTR_ADAPTIVE 58
+#define STORE_ATTR_INSTANCE_VALUE 59
+#define STORE_ATTR_SLOT 62
+#define STORE_ATTR_WITH_HINT 63
+#define LOAD_FAST__LOAD_FAST 64
+#define STORE_FAST__LOAD_FAST 65
+#define LOAD_FAST__LOAD_CONST 66
+#define LOAD_CONST__LOAD_FAST 67
+#define STORE_FAST__STORE_FAST 75
#define DO_TRACING 255
#ifdef NEED_OPCODE_JUMP_TABLES
static uint32_t _PyOpcode_RelativeJump[8] = {
"BINARY_OP_INPLACE_ADD_UNICODE",
"BINARY_OP_MULTIPLY_INT",
"BINARY_OP_MULTIPLY_FLOAT",
+ "BINARY_OP_SUBTRACT_INT",
+ "BINARY_OP_SUBTRACT_FLOAT",
"BINARY_SUBSCR_ADAPTIVE",
"BINARY_SUBSCR_LIST_INT",
"BINARY_SUBSCR_TUPLE_INT",
return _PyLong_Add(a, b);
}
-
-static PyObject *
-long_sub(PyLongObject *a, PyLongObject *b)
+PyObject *
+_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
{
PyLongObject *z;
- CHECK_BINOP(a, b);
-
if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) {
return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
}
return (PyObject *)z;
}
+static PyObject *
+long_sub(PyLongObject *a, PyLongObject *b)
+{
+ CHECK_BINOP(a, b);
+ return _PyLong_Subtract(a, b);
+}
+
/* Grade school multiplication, ignoring the signs.
* Returns the absolute value of the product, or NULL if error.
*/
DISPATCH();
}
+ TARGET(BINARY_OP_SUBTRACT_INT) {
+ PyObject *left = SECOND();
+ PyObject *right = TOP();
+ DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
+ STAT_INC(BINARY_OP, hit);
+ PyObject *sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
+ SET_SECOND(sub);
+ Py_DECREF(right);
+ Py_DECREF(left);
+ STACK_SHRINK(1);
+ if (sub == NULL) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
+ TARGET(BINARY_OP_SUBTRACT_FLOAT) {
+ PyObject *left = SECOND();
+ PyObject *right = TOP();
+ DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
+ STAT_INC(BINARY_OP, hit);
+ double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval;
+ PyObject *sub = PyFloat_FromDouble(dsub);
+ SET_SECOND(sub);
+ Py_DECREF(right);
+ Py_DECREF(left);
+ STACK_SHRINK(1);
+ if (sub == NULL) {
+ goto error;
+ }
+ DISPATCH();
+ }
+
TARGET(BINARY_OP_ADD_UNICODE) {
PyObject *left = SECOND();
PyObject *right = TOP();
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
&&TARGET_BINARY_OP_MULTIPLY_INT,
&&TARGET_BINARY_OP_MULTIPLY_FLOAT,
+ &&TARGET_BINARY_OP_SUBTRACT_INT,
+ &&TARGET_BINARY_OP_SUBTRACT_FLOAT,
&&TARGET_BINARY_SUBSCR_ADAPTIVE,
&&TARGET_BINARY_SUBSCR_LIST_INT,
&&TARGET_BINARY_SUBSCR_TUPLE_INT,
&&TARGET_BINARY_SUBSCR_DICT,
+ &&TARGET_BINARY_SUBSCR,
&&TARGET_CALL_FUNCTION_ADAPTIVE,
&&TARGET_CALL_FUNCTION_BUILTIN_O,
- &&TARGET_BINARY_SUBSCR,
&&TARGET_CALL_FUNCTION_BUILTIN_FAST,
&&TARGET_CALL_FUNCTION_LEN,
- &&TARGET_CALL_FUNCTION_ISINSTANCE,
- &&TARGET_CALL_FUNCTION_PY_SIMPLE,
&&TARGET_GET_LEN,
&&TARGET_MATCH_MAPPING,
&&TARGET_MATCH_SEQUENCE,
&&TARGET_MATCH_KEYS,
- &&TARGET_JUMP_ABSOLUTE_QUICK,
+ &&TARGET_CALL_FUNCTION_ISINSTANCE,
&&TARGET_PUSH_EXC_INFO,
- &&TARGET_LOAD_ATTR_ADAPTIVE,
+ &&TARGET_CALL_FUNCTION_PY_SIMPLE,
&&TARGET_POP_EXCEPT_AND_RERAISE,
+ &&TARGET_JUMP_ABSOLUTE_QUICK,
+ &&TARGET_LOAD_ATTR_ADAPTIVE,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ATTR_WITH_HINT,
&&TARGET_LOAD_ATTR_SLOT,
&&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_LOAD_METHOD_ADAPTIVE,
&&TARGET_LOAD_METHOD_CACHED,
- &&TARGET_LOAD_METHOD_CLASS,
- &&TARGET_LOAD_METHOD_MODULE,
&&TARGET_WITH_EXCEPT_START,
&&TARGET_GET_AITER,
&&TARGET_GET_ANEXT,
&&TARGET_BEFORE_ASYNC_WITH,
&&TARGET_BEFORE_WITH,
&&TARGET_END_ASYNC_FOR,
+ &&TARGET_LOAD_METHOD_CLASS,
+ &&TARGET_LOAD_METHOD_MODULE,
&&TARGET_LOAD_METHOD_NO_DICT,
&&TARGET_STORE_ATTR_ADAPTIVE,
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
- &&TARGET_STORE_ATTR_SLOT,
- &&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_STORE_SUBSCR,
&&TARGET_DELETE_SUBSCR,
+ &&TARGET_STORE_ATTR_SLOT,
+ &&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_LOAD_FAST__LOAD_FAST,
&&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_LOAD_FAST__LOAD_CONST,
&&TARGET_LOAD_CONST__LOAD_FAST,
- &&TARGET_STORE_FAST__STORE_FAST,
- &&_unknown_opcode,
&&TARGET_GET_ITER,
&&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_PRINT_EXPR,
&&TARGET_YIELD_FROM,
&&TARGET_GET_AWAITABLE,
&&TARGET_LOAD_ASSERTION_ERROR,
- &&_unknown_opcode,
+ &&TARGET_STORE_FAST__STORE_FAST,
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
goto success;
}
break;
+ case NB_SUBTRACT:
+ case NB_INPLACE_SUBTRACT:
+ if (PyLong_CheckExact(lhs)) {
+ *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT,
+ _Py_OPARG(*instr));
+ goto success;
+ }
+ if (PyFloat_CheckExact(lhs)) {
+ *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_FLOAT,
+ _Py_OPARG(*instr));
+ goto success;
+ }
+ break;
default:
// These operators don't have any available specializations. Rather
// than repeatedly attempting to specialize them, just convert them