diff options
| author | Andrea Corallo | 2019-08-11 17:21:23 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:33:59 +0100 |
| commit | 74635dafacb9ebb640a4a69108dabdd897c2498f (patch) | |
| tree | e19cb8547a1a8cc60f3cd680972a1dfe851ee8ed /src | |
| parent | 29e17e08b395db8e08e4c91a543750f8021376e8 (diff) | |
| download | emacs-74635dafacb9ebb640a4a69108dabdd897c2498f.tar.gz emacs-74635dafacb9ebb640a4a69108dabdd897c2498f.zip | |
C support for new prologue mechanism
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 171 |
1 files changed, 97 insertions, 74 deletions
diff --git a/src/comp.c b/src/comp.c index 881a78b3d75..acc727c772f 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -1013,74 +1013,6 @@ emit_set_internal (Lisp_Object args) | |||
| 1013 | return emit_call ("set_internal", comp.void_type , 4, gcc_args); | 1013 | return emit_call ("set_internal", comp.void_type , 4, gcc_args); |
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | static void | ||
| 1017 | emit_limple_ncall_prolog (EMACS_UINT n) | ||
| 1018 | { | ||
| 1019 | /* | ||
| 1020 | nargs will be known at runtime therfore we emit: | ||
| 1021 | |||
| 1022 | prologue: | ||
| 1023 | local[0] = *args; | ||
| 1024 | ++args; | ||
| 1025 | . | ||
| 1026 | . | ||
| 1027 | . | ||
| 1028 | local[min_args - 1] = *args; | ||
| 1029 | ++args; | ||
| 1030 | local[min_args] = list (nargs - min_args, args); | ||
| 1031 | bb_1: | ||
| 1032 | . | ||
| 1033 | . | ||
| 1034 | . | ||
| 1035 | */ | ||
| 1036 | gcc_jit_lvalue *nargs = | ||
| 1037 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 0)); | ||
| 1038 | gcc_jit_lvalue *args = | ||
| 1039 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 1)); | ||
| 1040 | gcc_jit_rvalue *min_args = | ||
| 1041 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1042 | comp.ptrdiff_type, | ||
| 1043 | n); | ||
| 1044 | |||
| 1045 | for (ptrdiff_t i = 0; i < n; ++i) | ||
| 1046 | { | ||
| 1047 | gcc_jit_block_add_assignment (comp.block, | ||
| 1048 | NULL, | ||
| 1049 | comp.frame[i], | ||
| 1050 | gcc_jit_lvalue_as_rvalue ( | ||
| 1051 | gcc_jit_rvalue_dereference ( | ||
| 1052 | gcc_jit_lvalue_as_rvalue (args), | ||
| 1053 | NULL))); | ||
| 1054 | |||
| 1055 | gcc_jit_block_add_assignment (comp.block, | ||
| 1056 | NULL, | ||
| 1057 | args, | ||
| 1058 | emit_ptr_arithmetic ( | ||
| 1059 | gcc_jit_lvalue_as_rvalue (args), | ||
| 1060 | comp.lisp_obj_ptr_type, | ||
| 1061 | sizeof (Lisp_Object), | ||
| 1062 | comp.one)); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* | ||
| 1066 | rest arguments | ||
| 1067 | */ | ||
| 1068 | gcc_jit_rvalue *list_args[] = | ||
| 1069 | { gcc_jit_context_new_binary_op (comp.ctxt, | ||
| 1070 | NULL, | ||
| 1071 | GCC_JIT_BINARY_OP_MINUS, | ||
| 1072 | comp.ptrdiff_type, | ||
| 1073 | gcc_jit_lvalue_as_rvalue (nargs), | ||
| 1074 | min_args), | ||
| 1075 | gcc_jit_lvalue_as_rvalue (args) }; | ||
| 1076 | |||
| 1077 | gcc_jit_block_add_assignment (comp.block, | ||
| 1078 | NULL, | ||
| 1079 | comp.frame[n], | ||
| 1080 | emit_call ("Flist", comp.lisp_obj_type, 2, | ||
| 1081 | list_args)); | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | /* This is for a regular function with arguments as m-var. */ | 1016 | /* This is for a regular function with arguments as m-var. */ |
| 1085 | 1017 | ||
| 1086 | static gcc_jit_rvalue * | 1018 | static gcc_jit_rvalue * |
| @@ -1250,6 +1182,28 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1250 | 1182 | ||
| 1251 | emit_cond_jump (emit_EQ (a, b), target2, target1); | 1183 | emit_cond_jump (emit_EQ (a, b), target2, target1); |
| 1252 | } | 1184 | } |
| 1185 | else if (EQ (op, Qcond_jump_narg_leq)) | ||
| 1186 | { | ||
| 1187 | /* | ||
| 1188 | Limple: (cond-jump-narg-less 2 entry_2 entry_fallback_2) | ||
| 1189 | C: if (nargs < 2) goto entry2_fallback; else goto entry_2; | ||
| 1190 | */ | ||
| 1191 | gcc_jit_lvalue *nargs = | ||
| 1192 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 0)); | ||
| 1193 | gcc_jit_rvalue *n = | ||
| 1194 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1195 | comp.ptrdiff_type, | ||
| 1196 | XFIXNUM (arg0)); | ||
| 1197 | gcc_jit_block *target1 = retrive_block (SECOND (args)); | ||
| 1198 | gcc_jit_block *target2 = retrive_block (THIRD (args)); | ||
| 1199 | gcc_jit_rvalue *test = gcc_jit_context_new_comparison ( | ||
| 1200 | comp.ctxt, | ||
| 1201 | NULL, | ||
| 1202 | GCC_JIT_COMPARISON_LE, | ||
| 1203 | gcc_jit_lvalue_as_rvalue (nargs), | ||
| 1204 | n); | ||
| 1205 | emit_cond_jump (test, target2, target1); | ||
| 1206 | } | ||
| 1253 | else if (EQ (op, Qpush_handler)) | 1207 | else if (EQ (op, Qpush_handler)) |
| 1254 | { | 1208 | { |
| 1255 | EMACS_UINT clobber_slot = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); | 1209 | EMACS_UINT clobber_slot = XFIXNUM (FUNCALL1 (comp-mvar-slot, arg0)); |
| @@ -1272,8 +1226,10 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1272 | } | 1226 | } |
| 1273 | else if (EQ (op, Qpop_handler)) | 1227 | else if (EQ (op, Qpop_handler)) |
| 1274 | { | 1228 | { |
| 1275 | /* current_thread->m_handlerlist = | 1229 | /* |
| 1276 | current_thread->m_handlerlist->next; */ | 1230 | C: current_thread->m_handlerlist = |
| 1231 | current_thread->m_handlerlist->next; | ||
| 1232 | */ | ||
| 1277 | gcc_jit_lvalue *m_handlerlist = | 1233 | gcc_jit_lvalue *m_handlerlist = |
| 1278 | gcc_jit_rvalue_dereference_field (comp.current_thread, | 1234 | gcc_jit_rvalue_dereference_field (comp.current_thread, |
| 1279 | NULL, | 1235 | NULL, |
| @@ -1328,10 +1284,74 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1328 | comp.frame[slot_n], | 1284 | comp.frame[slot_n], |
| 1329 | param); | 1285 | param); |
| 1330 | } | 1286 | } |
| 1331 | else if (EQ (op, Qncall_prolog)) | 1287 | else if (EQ (op, Qset_args_to_local)) |
| 1288 | { | ||
| 1289 | /* | ||
| 1290 | Limple: (set-args-to-local 1) | ||
| 1291 | C: local[1] = *args; | ||
| 1292 | */ | ||
| 1293 | gcc_jit_rvalue *gcc_args = | ||
| 1294 | gcc_jit_lvalue_as_rvalue ( | ||
| 1295 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 1))); | ||
| 1296 | |||
| 1297 | gcc_jit_rvalue *res = | ||
| 1298 | gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference (gcc_args, NULL)); | ||
| 1299 | |||
| 1300 | EMACS_UINT slot_n = XFIXNUM (arg0); | ||
| 1301 | gcc_jit_block_add_assignment (comp.block, | ||
| 1302 | NULL, | ||
| 1303 | comp.frame[slot_n], | ||
| 1304 | res); | ||
| 1305 | } | ||
| 1306 | else if (EQ (op, Qset_rest_args_to_local)) | ||
| 1332 | { | 1307 | { |
| 1333 | /* Ex: (ncall-prolog 2). */ | 1308 | /* |
| 1334 | emit_limple_ncall_prolog (XFIXNUM (arg0)); | 1309 | Limple: (set-rest-args-to-local 3) |
| 1310 | C: local[3] = list (nargs - 3, args); | ||
| 1311 | */ | ||
| 1312 | gcc_jit_rvalue *n = | ||
| 1313 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1314 | comp.ptrdiff_type, | ||
| 1315 | XFIXNUM (arg0)); | ||
| 1316 | gcc_jit_lvalue *nargs = | ||
| 1317 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 0)); | ||
| 1318 | gcc_jit_lvalue *args = | ||
| 1319 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 1)); | ||
| 1320 | |||
| 1321 | gcc_jit_rvalue *list_args[] = | ||
| 1322 | { gcc_jit_context_new_binary_op (comp.ctxt, | ||
| 1323 | NULL, | ||
| 1324 | GCC_JIT_BINARY_OP_MINUS, | ||
| 1325 | comp.ptrdiff_type, | ||
| 1326 | gcc_jit_lvalue_as_rvalue (nargs), | ||
| 1327 | n), | ||
| 1328 | gcc_jit_lvalue_as_rvalue (args) }; | ||
| 1329 | |||
| 1330 | res = emit_call ("Flist", comp.lisp_obj_type, 2, | ||
| 1331 | list_args); | ||
| 1332 | |||
| 1333 | gcc_jit_block_add_assignment (comp.block, | ||
| 1334 | NULL, | ||
| 1335 | comp.frame[XFIXNUM (arg0)], | ||
| 1336 | res); | ||
| 1337 | } | ||
| 1338 | else if (EQ (op, Qinc_args)) | ||
| 1339 | { | ||
| 1340 | /* | ||
| 1341 | Limple: (inc-args) | ||
| 1342 | C: ++args; | ||
| 1343 | */ | ||
| 1344 | gcc_jit_lvalue *args = | ||
| 1345 | gcc_jit_param_as_lvalue (gcc_jit_function_get_param (comp.func, 1)); | ||
| 1346 | |||
| 1347 | gcc_jit_block_add_assignment (comp.block, | ||
| 1348 | NULL, | ||
| 1349 | args, | ||
| 1350 | emit_ptr_arithmetic ( | ||
| 1351 | gcc_jit_lvalue_as_rvalue (args), | ||
| 1352 | comp.lisp_obj_ptr_type, | ||
| 1353 | sizeof (Lisp_Object), | ||
| 1354 | comp.one)); | ||
| 1335 | } | 1355 | } |
| 1336 | else if (EQ (op, Qsetimm)) | 1356 | else if (EQ (op, Qsetimm)) |
| 1337 | { | 1357 | { |
| @@ -2456,11 +2476,14 @@ syms_of_comp (void) | |||
| 2456 | DEFSYM (Qcallref, "callref"); | 2476 | DEFSYM (Qcallref, "callref"); |
| 2457 | DEFSYM (Qncall, "ncall"); | 2477 | DEFSYM (Qncall, "ncall"); |
| 2458 | DEFSYM (Qsetpar, "setpar"); | 2478 | DEFSYM (Qsetpar, "setpar"); |
| 2459 | DEFSYM (Qncall_prolog, "ncall-prolog"); | ||
| 2460 | DEFSYM (Qsetimm, "setimm"); | 2479 | DEFSYM (Qsetimm, "setimm"); |
| 2461 | DEFSYM (Qreturn, "return"); | 2480 | DEFSYM (Qreturn, "return"); |
| 2462 | DEFSYM (Qcomp_mvar, "comp-mvar"); | 2481 | DEFSYM (Qcomp_mvar, "comp-mvar"); |
| 2463 | DEFSYM (Qcond_jump, "cond-jump"); | 2482 | DEFSYM (Qcond_jump, "cond-jump"); |
| 2483 | DEFSYM (Qset_args_to_local, "set-args-to-local"); | ||
| 2484 | DEFSYM (Qset_rest_args_to_local, "set-rest-args-to-local"); | ||
| 2485 | DEFSYM (Qinc_args, "inc-args"); | ||
| 2486 | DEFSYM (Qcond_jump_narg_leq, "cond-jump-narg-leq"); | ||
| 2464 | DEFSYM (Qpush_handler, "push-handler"); | 2487 | DEFSYM (Qpush_handler, "push-handler"); |
| 2465 | DEFSYM (Qpop_handler, "pop-handler"); | 2488 | DEFSYM (Qpop_handler, "pop-handler"); |
| 2466 | DEFSYM (Qcondition_case, "condition-case"); | 2489 | DEFSYM (Qcondition_case, "condition-case"); |