aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd2021-12-30 18:48:53 +0100
committerMattias EngdegÄrd2022-01-02 14:01:31 +0100
commit5dd261282d28548609f9cfc9d63811fa02639549 (patch)
treea506cd5bd35521f2a920b707059e27d477c831e3 /src/bytecode.c
parent43932a0d90c2e416e4e315397dd7df503b2d1fd6 (diff)
downloademacs-5dd261282d28548609f9cfc9d63811fa02639549.tar.gz
emacs-5dd261282d28548609f9cfc9d63811fa02639549.zip
Inline fixnum operations in bytecode interpreter
Since numeric operations are mostly done on fixnums, this gives a speed-up for common code. * src/bytecode.c (exec_byte_code): Inline fixnum comparisons and operations with fixnum results: =, >, <, <=, >=, -, +, -, *, /, %, max and min.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c138
1 files changed, 108 insertions, 30 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index f8ffec0348a..5d8842f40cb 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1032,43 +1032,72 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1032 1032
1033 CASE (Beqlsign): 1033 CASE (Beqlsign):
1034 { 1034 {
1035 Lisp_Object v1 = POP; 1035 Lisp_Object v2 = POP;
1036 TOP = arithcompare (TOP, v1, ARITH_EQUAL); 1036 Lisp_Object v1 = TOP;
1037 if (FIXNUMP (v1) && FIXNUMP (v2))
1038 TOP = EQ (v1, v2) ? Qt : Qnil;
1039 else
1040 TOP = arithcompare (v1, v2, ARITH_EQUAL);
1037 NEXT; 1041 NEXT;
1038 } 1042 }
1039 1043
1040 CASE (Bgtr): 1044 CASE (Bgtr):
1041 { 1045 {
1042 Lisp_Object v1 = POP; 1046 Lisp_Object v2 = POP;
1043 TOP = arithcompare (TOP, v1, ARITH_GRTR); 1047 Lisp_Object v1 = TOP;
1048 if (FIXNUMP (v1) && FIXNUMP (v2))
1049 TOP = XFIXNUM (v1) > XFIXNUM (v2) ? Qt : Qnil;
1050 else
1051 TOP = arithcompare (v1, v2, ARITH_GRTR);
1044 NEXT; 1052 NEXT;
1045 } 1053 }
1046 1054
1047 CASE (Blss): 1055 CASE (Blss):
1048 { 1056 {
1049 Lisp_Object v1 = POP; 1057 Lisp_Object v2 = POP;
1050 TOP = arithcompare (TOP, v1, ARITH_LESS); 1058 Lisp_Object v1 = TOP;
1059 if (FIXNUMP (v1) && FIXNUMP (v2))
1060 TOP = XFIXNUM (v1) < XFIXNUM (v2) ? Qt : Qnil;
1061 else
1062 TOP = arithcompare (v1, v2, ARITH_LESS);
1051 NEXT; 1063 NEXT;
1052 } 1064 }
1053 1065
1054 CASE (Bleq): 1066 CASE (Bleq):
1055 { 1067 {
1056 Lisp_Object v1 = POP; 1068 Lisp_Object v2 = POP;
1057 TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL); 1069 Lisp_Object v1 = TOP;
1070 if (FIXNUMP (v1) && FIXNUMP (v2))
1071 TOP = XFIXNUM (v1) <= XFIXNUM (v2) ? Qt : Qnil;
1072 else
1073 TOP = arithcompare (v1, v2, ARITH_LESS_OR_EQUAL);
1058 NEXT; 1074 NEXT;
1059 } 1075 }
1060 1076
1061 CASE (Bgeq): 1077 CASE (Bgeq):
1062 { 1078 {
1063 Lisp_Object v1 = POP; 1079 Lisp_Object v2 = POP;
1064 TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL); 1080 Lisp_Object v1 = TOP;
1081 if (FIXNUMP (v1) && FIXNUMP (v2))
1082 TOP = XFIXNUM (v1) >= XFIXNUM (v2) ? Qt : Qnil;
1083 else
1084 TOP = arithcompare (v1, v2, ARITH_GRTR_OR_EQUAL);
1065 NEXT; 1085 NEXT;
1066 } 1086 }
1067 1087
1068 CASE (Bdiff): 1088 CASE (Bdiff):
1069 DISCARD (1); 1089 {
1070 TOP = Fminus (2, &TOP); 1090 Lisp_Object v2 = POP;
1071 NEXT; 1091 Lisp_Object v1 = TOP;
1092 EMACS_INT res;
1093 if (FIXNUMP (v1) && FIXNUMP (v2)
1094 && (res = XFIXNUM (v1) - XFIXNUM (v2),
1095 !FIXNUM_OVERFLOW_P (res)))
1096 TOP = make_fixnum (res);
1097 else
1098 TOP = Fminus (2, &TOP);
1099 NEXT;
1100 }
1072 1101
1073 CASE (Bnegate): 1102 CASE (Bnegate):
1074 TOP = (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM 1103 TOP = (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM
@@ -1077,34 +1106,83 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1077 NEXT; 1106 NEXT;
1078 1107
1079 CASE (Bplus): 1108 CASE (Bplus):
1080 DISCARD (1); 1109 {
1081 TOP = Fplus (2, &TOP); 1110 Lisp_Object v2 = POP;
1082 NEXT; 1111 Lisp_Object v1 = TOP;
1112 EMACS_INT res;
1113 if (FIXNUMP (v1) && FIXNUMP (v2)
1114 && (res = XFIXNUM (v1) + XFIXNUM (v2),
1115 !FIXNUM_OVERFLOW_P (res)))
1116 TOP = make_fixnum (res);
1117 else
1118 TOP = Fplus (2, &TOP);
1119 NEXT;
1120 }
1083 1121
1084 CASE (Bmax): 1122 CASE (Bmax):
1085 DISCARD (1); 1123 {
1086 TOP = Fmax (2, &TOP); 1124 Lisp_Object v2 = POP;
1087 NEXT; 1125 Lisp_Object v1 = TOP;
1126 if (FIXNUMP (v1) && FIXNUMP (v2))
1127 {
1128 if (XFIXNUM (v2) > XFIXNUM (v1))
1129 TOP = v2;
1130 }
1131 else
1132 TOP = Fmax (2, &TOP);
1133 NEXT;
1134 }
1088 1135
1089 CASE (Bmin): 1136 CASE (Bmin):
1090 DISCARD (1); 1137 {
1091 TOP = Fmin (2, &TOP); 1138 Lisp_Object v2 = POP;
1092 NEXT; 1139 Lisp_Object v1 = TOP;
1140 if (FIXNUMP (v1) && FIXNUMP (v2))
1141 {
1142 if (XFIXNUM (v2) < XFIXNUM (v1))
1143 TOP = v2;
1144 }
1145 else
1146 TOP = Fmin (2, &TOP);
1147 NEXT;
1148 }
1093 1149
1094 CASE (Bmult): 1150 CASE (Bmult):
1095 DISCARD (1); 1151 {
1096 TOP = Ftimes (2, &TOP); 1152 Lisp_Object v2 = POP;
1097 NEXT; 1153 Lisp_Object v1 = TOP;
1154 intmax_t res;
1155 if (FIXNUMP (v1) && FIXNUMP (v2)
1156 && !INT_MULTIPLY_WRAPV (XFIXNUM (v1), XFIXNUM (v2), &res)
1157 && !FIXNUM_OVERFLOW_P (res))
1158 TOP = make_fixnum (res);
1159 else
1160 TOP = Ftimes (2, &TOP);
1161 NEXT;
1162 }
1098 1163
1099 CASE (Bquo): 1164 CASE (Bquo):
1100 DISCARD (1); 1165 {
1101 TOP = Fquo (2, &TOP); 1166 Lisp_Object v2 = POP;
1102 NEXT; 1167 Lisp_Object v1 = TOP;
1168 EMACS_INT res;
1169 if (FIXNUMP (v1) && FIXNUMP (v2) && XFIXNUM (v2) != 0
1170 && (res = XFIXNUM (v1) / XFIXNUM (v2),
1171 !FIXNUM_OVERFLOW_P (res)))
1172 TOP = make_fixnum (res);
1173 else
1174 TOP = Fquo (2, &TOP);
1175 NEXT;
1176 }
1103 1177
1104 CASE (Brem): 1178 CASE (Brem):
1105 { 1179 {
1106 Lisp_Object v1 = POP; 1180 Lisp_Object v2 = POP;
1107 TOP = Frem (TOP, v1); 1181 Lisp_Object v1 = TOP;
1182 if (FIXNUMP (v1) && FIXNUMP (v2) && XFIXNUM (v2) != 0)
1183 TOP = make_fixnum (XFIXNUM (v1) % XFIXNUM (v2));
1184 else
1185 TOP = Frem (v1, v2);
1108 NEXT; 1186 NEXT;
1109 } 1187 }
1110 1188