diff options
| author | Andrea Corallo | 2019-08-31 17:06:45 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:40 +0100 |
| commit | 9413488ab4e8752a2fe88ce9f42ca83ffbe5f1a8 (patch) | |
| tree | ee84281c03623aaf9b5c67e8c0b7c7f07bbdad0c /src | |
| parent | ad5488cad62b04ff1ae28cbbe2a0dcb2af817f27 (diff) | |
| download | emacs-9413488ab4e8752a2fe88ce9f42ca83ffbe5f1a8.tar.gz emacs-9413488ab4e8752a2fe88ce9f42ca83ffbe5f1a8.zip | |
reloc emission mechanism seems ok
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 236 |
1 files changed, 151 insertions, 85 deletions
diff --git a/src/comp.c b/src/comp.c index 1a2984bb72e..d7e82845454 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -149,8 +149,8 @@ typedef struct { | |||
| 149 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ | 149 | Lisp_Object func_blocks; /* blk_name -> gcc_block. */ |
| 150 | Lisp_Object func_hash; /* c_f_name -> (gcc_func . subr_name). */ | 150 | Lisp_Object func_hash; /* c_f_name -> (gcc_func . subr_name). */ |
| 151 | Lisp_Object emitter_dispatcher; | 151 | Lisp_Object emitter_dispatcher; |
| 152 | gcc_jit_rvalue *data_relocs; | 152 | gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ |
| 153 | gcc_jit_lvalue *func_relocs; | 153 | gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ |
| 154 | } comp_t; | 154 | } comp_t; |
| 155 | 155 | ||
| 156 | static comp_t comp; | 156 | static comp_t comp; |
| @@ -270,53 +270,72 @@ emit_comment (const char *str) | |||
| 270 | str); | 270 | str); |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | static void | 273 | /* |
| 274 | fill_declaration_types (gcc_jit_type **type, gcc_jit_rvalue **args, | 274 | Declare an imported function. |
| 275 | unsigned nargs) | 275 | When nargs is MANY (ptrdiff_t nargs, Lisp_Object *args) signature is assumed. |
| 276 | { | 276 | When types is NULL types is assumed to be all Lisp_Objects. |
| 277 | /* If args are passed types are extracted from that otherwise assume params */ | 277 | */ |
| 278 | /* are all lisp objs. */ | ||
| 279 | if (args) | ||
| 280 | for (unsigned i = 0; i < nargs; i++) | ||
| 281 | type[i] = gcc_jit_rvalue_get_type (args[i]); | ||
| 282 | else | ||
| 283 | for (unsigned i = 0; i < nargs; i++) | ||
| 284 | type[i] = comp.lisp_obj_type; | ||
| 285 | } | ||
| 286 | |||
| 287 | static gcc_jit_field * | 278 | static gcc_jit_field * |
| 288 | declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type, | 279 | declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type, |
| 289 | unsigned nargs, gcc_jit_rvalue **args) | 280 | int nargs, gcc_jit_type **types) |
| 290 | { | 281 | { |
| 291 | /* Don't want to declare the same function two times. */ | 282 | /* Don't want to declare the same function two times. */ |
| 292 | eassert (NILP (Fgethash (subr_sym, comp.func_hash, Qnil))); | 283 | eassert (NILP (Fgethash (subr_sym, comp.func_hash, Qnil))); |
| 293 | 284 | ||
| 294 | gcc_jit_type *type[nargs]; | 285 | if (nargs == MANY) |
| 295 | fill_declaration_types (type, args, nargs); | 286 | { |
| 287 | nargs = 2; | ||
| 288 | types = alloca (nargs * sizeof (* types)); | ||
| 289 | types[0] = comp.ptrdiff_type; | ||
| 290 | types[1] = comp.lisp_obj_type; | ||
| 291 | } | ||
| 292 | else if (!types) | ||
| 293 | { | ||
| 294 | types = alloca (nargs * sizeof (* types)); | ||
| 295 | for (unsigned i = 0; i < nargs; i++) | ||
| 296 | types[i] = comp.lisp_obj_type; | ||
| 297 | } | ||
| 298 | |||
| 299 | eassert (types); | ||
| 296 | 300 | ||
| 297 | /* String containing the function ptr name. */ | 301 | /* String containing the function ptr name. */ |
| 298 | Lisp_Object f_ptr_name | 302 | Lisp_Object f_ptr_name = |
| 299 | = CALLN (Ffuncall, intern_c_string (STR (comp-c-func-name)), | 303 | CALLN (Ffuncall, intern_c_string (STR (comp-c-func-name)), |
| 300 | subr_sym, make_string("R", 1)); | 304 | subr_sym, make_string("R", 1)); |
| 301 | 305 | ||
| 302 | gcc_jit_type *f_ptr_type | 306 | gcc_jit_type *f_ptr_type = |
| 303 | = gcc_jit_context_new_function_ptr_type (comp.ctxt, | 307 | gcc_jit_context_new_function_ptr_type (comp.ctxt, |
| 304 | NULL, | 308 | NULL, |
| 305 | ret_type, | 309 | ret_type, |
| 306 | nargs, | 310 | nargs, |
| 307 | type, | 311 | types, |
| 308 | 0); | 312 | 0); |
| 309 | gcc_jit_field *field | 313 | gcc_jit_field *field = |
| 310 | = gcc_jit_context_new_field (comp.ctxt, | 314 | gcc_jit_context_new_field (comp.ctxt, |
| 311 | NULL, | 315 | NULL, |
| 312 | f_ptr_type, | 316 | f_ptr_type, |
| 313 | SSDATA (f_ptr_name)); | 317 | SSDATA (f_ptr_name)); |
| 318 | |||
| 314 | 319 | ||
| 315 | Lisp_Object value = Fcons (make_mint_ptr (field), subr_sym); | 320 | Lisp_Object value = Fcons (make_mint_ptr (field), subr_sym); |
| 316 | Fputhash (subr_sym, value, comp.func_hash); | 321 | Fputhash (subr_sym, value, comp.func_hash); |
| 317 | return field; | 322 | return field; |
| 318 | } | 323 | } |
| 319 | 324 | ||
| 325 | static void | ||
| 326 | fill_declaration_types (gcc_jit_type **type, gcc_jit_rvalue **args, | ||
| 327 | unsigned nargs) | ||
| 328 | { | ||
| 329 | /* If args are passed types are extracted from that otherwise assume params */ | ||
| 330 | /* are all lisp objs. */ | ||
| 331 | if (args) | ||
| 332 | for (unsigned i = 0; i < nargs; i++) | ||
| 333 | type[i] = gcc_jit_rvalue_get_type (args[i]); | ||
| 334 | else | ||
| 335 | for (unsigned i = 0; i < nargs; i++) | ||
| 336 | type[i] = comp.lisp_obj_type; | ||
| 337 | } | ||
| 338 | |||
| 320 | static gcc_jit_function * | 339 | static gcc_jit_function * |
| 321 | declare_exported_func (const char *f_name, gcc_jit_type *ret_type, | 340 | declare_exported_func (const char *f_name, gcc_jit_type *ret_type, |
| 322 | unsigned nargs, gcc_jit_rvalue **args) | 341 | unsigned nargs, gcc_jit_rvalue **args) |
| @@ -351,6 +370,9 @@ emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, unsigned nargs, | |||
| 351 | gcc_jit_lvalue_access_field (comp.func_relocs, | 370 | gcc_jit_lvalue_access_field (comp.func_relocs, |
| 352 | NULL, | 371 | NULL, |
| 353 | (gcc_jit_field *) xmint_pointer (XCAR (value))); | 372 | (gcc_jit_field *) xmint_pointer (XCAR (value))); |
| 373 | if (!f_ptr) | ||
| 374 | error ("Undeclared function relocation."); | ||
| 375 | |||
| 354 | emit_comment (format_string ("calling subr: %s", | 376 | emit_comment (format_string ("calling subr: %s", |
| 355 | SSDATA (SYMBOL_NAME (subr_sym)))); | 377 | SSDATA (SYMBOL_NAME (subr_sym)))); |
| 356 | return gcc_jit_context_new_call_through_ptr(comp.ctxt, | 378 | return gcc_jit_context_new_call_through_ptr(comp.ctxt, |
| @@ -1524,6 +1546,38 @@ emit_litteral_string_func (const char *str_name, const char *str) | |||
| 1524 | } | 1546 | } |
| 1525 | 1547 | ||
| 1526 | /* | 1548 | /* |
| 1549 | Declare as imported all the functions that are requested from the runtime. | ||
| 1550 | These are either subrs or not. | ||
| 1551 | */ | ||
| 1552 | static Lisp_Object | ||
| 1553 | declare_runtime_imported (void) | ||
| 1554 | { | ||
| 1555 | /* For subr imported by the runtime we rely on the standard mechanism in place | ||
| 1556 | for functions imported by lisp code. */ | ||
| 1557 | FUNCALL1 (comp-add-subr-to-relocs, intern_c_string ("1+")); | ||
| 1558 | FUNCALL1 (comp-add-subr-to-relocs, intern_c_string ("1-")); | ||
| 1559 | FUNCALL1 (comp-add-subr-to-relocs, intern_c_string ("+")); | ||
| 1560 | FUNCALL1 (comp-add-subr-to-relocs, intern_c_string ("-")); | ||
| 1561 | |||
| 1562 | Lisp_Object field_list = Qnil; | ||
| 1563 | #define ADD_IMPORTED(f_name, ret_type, nargs, args) \ | ||
| 1564 | { \ | ||
| 1565 | Lisp_Object name = intern_c_string (f_name); \ | ||
| 1566 | Lisp_Object field = \ | ||
| 1567 | make_mint_ptr (declare_imported_func (name, ret_type, nargs, args)); \ | ||
| 1568 | field_list = Fcons (field, field_list); \ | ||
| 1569 | } while (0) | ||
| 1570 | |||
| 1571 | ADD_IMPORTED ("wrong_type_argument", comp.void_type, 2, NULL); | ||
| 1572 | gcc_jit_type *args[] = {comp.lisp_obj_type, comp.int_type}; | ||
| 1573 | ADD_IMPORTED ("helper_PSEUDOVECTOR_TYPEP_XUNTAG", comp.bool_type, 2, args); | ||
| 1574 | ADD_IMPORTED ("pure_write_error", comp.void_type, 1, NULL); | ||
| 1575 | #undef ADD_IMPORTED | ||
| 1576 | |||
| 1577 | return field_list; | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | /* | ||
| 1527 | This emit the code needed by every compilation unit to be loaded. | 1581 | This emit the code needed by every compilation unit to be loaded. |
| 1528 | */ | 1582 | */ |
| 1529 | static void | 1583 | static void |
| @@ -1536,49 +1590,61 @@ emit_ctxt_code (void) | |||
| 1536 | XFIXNUM (FUNCALL1 (hash-table-count, | 1590 | XFIXNUM (FUNCALL1 (hash-table-count, |
| 1537 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); | 1591 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); |
| 1538 | 1592 | ||
| 1539 | comp.data_relocs | 1593 | comp.data_relocs = |
| 1540 | = gcc_jit_lvalue_as_rvalue( | 1594 | gcc_jit_lvalue_as_rvalue( |
| 1541 | gcc_jit_context_new_global ( | 1595 | gcc_jit_context_new_global ( |
| 1542 | comp.ctxt, | 1596 | comp.ctxt, |
| 1543 | NULL, | 1597 | NULL, |
| 1544 | GCC_JIT_GLOBAL_EXPORTED, | 1598 | GCC_JIT_GLOBAL_EXPORTED, |
| 1545 | gcc_jit_context_new_array_type (comp.ctxt, | 1599 | gcc_jit_context_new_array_type (comp.ctxt, |
| 1546 | NULL, | 1600 | NULL, |
| 1547 | comp.lisp_obj_type, | 1601 | comp.lisp_obj_type, |
| 1548 | d_reloc_len), | 1602 | d_reloc_len), |
| 1549 | "data_relocs")); | 1603 | "data_relocs")); |
| 1550 | 1604 | ||
| 1551 | emit_litteral_string_func ("text_data_relocs", d_reloc); | 1605 | emit_litteral_string_func ("text_data_relocs", d_reloc); |
| 1552 | 1606 | ||
| 1553 | /* Imported functions. */ | 1607 | /* Imported functions from non Lisp code. */ |
| 1554 | Lisp_Object f_reloc = FUNCALL1 (comp-ctxt-func-relocs-l, Vcomp_ctxt); | 1608 | Lisp_Object f_runtime = declare_runtime_imported (); |
| 1555 | EMACS_UINT f_reloc_len = XFIXNUM (Flength (f_reloc)); | 1609 | EMACS_UINT f_reloc_len = XFIXNUM (Flength (f_runtime)); |
| 1610 | |||
| 1611 | /* Imported subrs. */ | ||
| 1612 | Lisp_Object f_subr = FUNCALL1 (comp-ctxt-func-relocs-l, Vcomp_ctxt); | ||
| 1613 | f_reloc_len += XFIXNUM (Flength (f_subr)); | ||
| 1614 | |||
| 1556 | gcc_jit_field *fields[f_reloc_len]; | 1615 | gcc_jit_field *fields[f_reloc_len]; |
| 1557 | int i = 0; | 1616 | int i = 0; |
| 1558 | FOR_EACH_TAIL (f_reloc) | 1617 | |
| 1618 | FOR_EACH_TAIL (f_runtime) | ||
| 1559 | { | 1619 | { |
| 1560 | Lisp_Object subr_sym = XCAR (f_reloc); | 1620 | fields[i++] = xmint_pointer( XCAR (f_runtime)); |
| 1621 | } | ||
| 1622 | |||
| 1623 | FOR_EACH_TAIL (f_subr) | ||
| 1624 | { | ||
| 1625 | Lisp_Object subr_sym = XCAR (f_subr); | ||
| 1561 | Lisp_Object subr = Fsymbol_function (subr_sym); | 1626 | Lisp_Object subr = Fsymbol_function (subr_sym); |
| 1562 | gcc_jit_field *field | 1627 | Lisp_Object maxarg = XCDR (Fsubr_arity (subr)); |
| 1563 | = declare_imported_func (subr_sym, comp.lisp_obj_type, | 1628 | gcc_jit_field *field = |
| 1564 | XFIXNUM (XCDR (Fsubr_arity (subr))), NULL); | 1629 | declare_imported_func (subr_sym, comp.lisp_obj_type, |
| 1630 | FIXNUMP (maxarg) ? XFIXNUM (maxarg) : MANY, NULL); | ||
| 1565 | fields [i++] = field; | 1631 | fields [i++] = field; |
| 1566 | } | 1632 | } |
| 1567 | eassert (f_reloc_len == i); | 1633 | eassert (f_reloc_len == i); |
| 1568 | 1634 | ||
| 1569 | gcc_jit_struct *f_reloc_struct | 1635 | gcc_jit_struct *f_reloc_struct = |
| 1570 | = gcc_jit_context_new_struct_type (comp.ctxt, | 1636 | gcc_jit_context_new_struct_type (comp.ctxt, |
| 1571 | NULL, | 1637 | NULL, |
| 1572 | "function_reloc_struct", | 1638 | "function_reloc_struct", |
| 1573 | f_reloc_len, | 1639 | f_reloc_len, |
| 1574 | fields); | 1640 | fields); |
| 1575 | comp.func_relocs | 1641 | comp.func_relocs = |
| 1576 | = gcc_jit_context_new_global ( | 1642 | gcc_jit_context_new_global ( |
| 1577 | comp.ctxt, | 1643 | comp.ctxt, |
| 1578 | NULL, | 1644 | NULL, |
| 1579 | GCC_JIT_GLOBAL_EXPORTED, | 1645 | GCC_JIT_GLOBAL_EXPORTED, |
| 1580 | gcc_jit_struct_as_type (f_reloc_struct), | 1646 | gcc_jit_struct_as_type (f_reloc_struct), |
| 1581 | "f_reloc"); | 1647 | "f_reloc"); |
| 1582 | 1648 | ||
| 1583 | /* Exported functions info. */ | 1649 | /* Exported functions info. */ |
| 1584 | const char *func_list = SSDATA (FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt)); | 1650 | const char *func_list = SSDATA (FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt)); |
| @@ -2332,18 +2398,18 @@ define_PSEUDOVECTORP (void) | |||
| 2332 | comp.bool_type, | 2398 | comp.bool_type, |
| 2333 | false)); | 2399 | false)); |
| 2334 | 2400 | ||
| 2335 | gcc_jit_rvalue *args[2] = | 2401 | gcc_jit_rvalue *args[] = |
| 2336 | { gcc_jit_param_as_rvalue (param[0]), | 2402 | { gcc_jit_param_as_rvalue (param[0]), |
| 2337 | gcc_jit_param_as_rvalue (param[1]) }; | 2403 | gcc_jit_param_as_rvalue (param[1]) }; |
| 2338 | comp.block = call_pseudovector_typep_b; | 2404 | comp.block = call_pseudovector_typep_b; |
| 2339 | /* FIXME use XUNTAG now that's available. */ | 2405 | /* FIXME use XUNTAG now that's available. */ |
| 2340 | gcc_jit_block_end_with_return (call_pseudovector_typep_b | 2406 | gcc_jit_block_end_with_return ( |
| 2341 | , | 2407 | call_pseudovector_typep_b, |
| 2342 | NULL, | 2408 | NULL, |
| 2343 | emit_call (intern_c_string ("helper_PSEUDOVECTOR_TYPEP_XUNTAG"), | 2409 | emit_call (intern_c_string ("helper_PSEUDOVECTOR_TYPEP_XUNTAG"), |
| 2344 | comp.bool_type, | 2410 | comp.bool_type, |
| 2345 | 2, | 2411 | 2, |
| 2346 | args)); | 2412 | args)); |
| 2347 | } | 2413 | } |
| 2348 | 2414 | ||
| 2349 | static void | 2415 | static void |
| @@ -2731,18 +2797,18 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, | |||
| 2731 | 2797 | ||
| 2732 | emit_ctxt_code (); | 2798 | emit_ctxt_code (); |
| 2733 | 2799 | ||
| 2734 | /* /\* Define inline functions. *\/ */ | 2800 | /* Define inline functions. */ |
| 2735 | /* define_CAR_CDR(); */ | 2801 | define_CAR_CDR(); |
| 2736 | /* define_PSEUDOVECTORP (); */ | 2802 | define_PSEUDOVECTORP (); |
| 2737 | /* define_CHECK_TYPE (); */ | 2803 | define_CHECK_TYPE (); |
| 2738 | /* define_CHECK_IMPURE (); */ | 2804 | define_CHECK_IMPURE (); |
| 2739 | /* define_bool_to_lisp_obj (); */ | 2805 | define_bool_to_lisp_obj (); |
| 2740 | /* define_setcar_setcdr (); */ | 2806 | define_setcar_setcdr (); |
| 2741 | /* define_add1_sub1 (); */ | 2807 | define_add1_sub1 (); |
| 2742 | /* define_negate (); */ | 2808 | define_negate (); |
| 2743 | 2809 | ||
| 2744 | /* Compile all functions. Can't be done before because the | 2810 | /* Compile all functions. Can't be done before because the |
| 2745 | relocation vectore has to be already compiled. */ | 2811 | relocation structs has to be already defined. */ |
| 2746 | struct Lisp_Hash_Table *func_h | 2812 | struct Lisp_Hash_Table *func_h |
| 2747 | = XHASH_TABLE (FUNCALL1 (comp-ctxt-funcs-h, Vcomp_ctxt)); | 2813 | = XHASH_TABLE (FUNCALL1 (comp-ctxt-funcs-h, Vcomp_ctxt)); |
| 2748 | for (ptrdiff_t i = 0; i < func_h->count; i++) | 2814 | for (ptrdiff_t i = 0; i < func_h->count; i++) |