diff options
| author | Andrea Corallo | 2020-04-04 23:33:52 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-04-05 21:10:56 +0100 |
| commit | 49a3790e684213a6247f20e8029947f82fefdb5b (patch) | |
| tree | e1c39ebc3e51dc27c127d3180f005c39468002e4 /src | |
| parent | 70cb9644817ef59446d0705ba1362f200b3bd13d (diff) | |
| download | emacs-49a3790e684213a6247f20e8029947f82fefdb5b.tar.gz emacs-49a3790e684213a6247f20e8029947f82fefdb5b.zip | |
* src/comp.c: Add MSB TAG and wide int support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 226 |
1 files changed, 194 insertions, 32 deletions
diff --git a/src/comp.c b/src/comp.c index f89414a3105..605e92680c7 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -101,6 +101,7 @@ typedef struct { | |||
| 101 | gcc_jit_type *long_long_type; | 101 | gcc_jit_type *long_long_type; |
| 102 | gcc_jit_type *unsigned_long_long_type; | 102 | gcc_jit_type *unsigned_long_long_type; |
| 103 | gcc_jit_type *emacs_int_type; | 103 | gcc_jit_type *emacs_int_type; |
| 104 | gcc_jit_type *emacs_uint_type; | ||
| 104 | gcc_jit_type *void_ptr_type; | 105 | gcc_jit_type *void_ptr_type; |
| 105 | gcc_jit_type *char_ptr_type; | 106 | gcc_jit_type *char_ptr_type; |
| 106 | gcc_jit_type *ptrdiff_type; | 107 | gcc_jit_type *ptrdiff_type; |
| @@ -155,8 +156,6 @@ typedef struct { | |||
| 155 | gcc_jit_block *block; /* Current basic block being compiled. */ | 156 | gcc_jit_block *block; /* Current basic block being compiled. */ |
| 156 | gcc_jit_lvalue *scratch; /* Used as scratch slot for some code sequence (switch). */ | 157 | gcc_jit_lvalue *scratch; /* Used as scratch slot for some code sequence (switch). */ |
| 157 | gcc_jit_lvalue ***arrays; /* Array index -> gcc_jit_lvalue **. */ | 158 | gcc_jit_lvalue ***arrays; /* Array index -> gcc_jit_lvalue **. */ |
| 158 | gcc_jit_rvalue *most_positive_fixnum; | ||
| 159 | gcc_jit_rvalue *most_negative_fixnum; | ||
| 160 | gcc_jit_rvalue *one; | 159 | gcc_jit_rvalue *one; |
| 161 | gcc_jit_rvalue *inttypebits; | 160 | gcc_jit_rvalue *inttypebits; |
| 162 | gcc_jit_rvalue *lisp_int0; | 161 | gcc_jit_rvalue *lisp_int0; |
| @@ -631,6 +630,85 @@ emit_cast (gcc_jit_type *new_type, gcc_jit_rvalue *obj) | |||
| 631 | dest_field); | 630 | dest_field); |
| 632 | } | 631 | } |
| 633 | 632 | ||
| 633 | |||
| 634 | /* Should come with libgccjit. */ | ||
| 635 | |||
| 636 | static gcc_jit_rvalue * | ||
| 637 | emit_rvalue_from_long_long (long long n) | ||
| 638 | { | ||
| 639 | #ifndef WIDE_EMACS_INT | ||
| 640 | xsignal1 (Qnative_ice, | ||
| 641 | build_string ("emit_rvalue_from_long_long called in non wide int" | ||
| 642 | " configuration")); | ||
| 643 | #endif | ||
| 644 | |||
| 645 | emit_comment (format_string ("emit long long: %lld", n)); | ||
| 646 | |||
| 647 | gcc_jit_rvalue *high = | ||
| 648 | gcc_jit_context_new_rvalue_from_long (comp.ctxt, | ||
| 649 | comp.unsigned_long_long_type, | ||
| 650 | (unsigned long long)n >> 32); | ||
| 651 | gcc_jit_rvalue *low = | ||
| 652 | emit_binary_op (GCC_JIT_BINARY_OP_RSHIFT, | ||
| 653 | comp.unsigned_long_long_type, | ||
| 654 | emit_binary_op (GCC_JIT_BINARY_OP_LSHIFT, | ||
| 655 | comp.unsigned_long_long_type, | ||
| 656 | gcc_jit_context_new_rvalue_from_long ( | ||
| 657 | comp.ctxt, | ||
| 658 | comp.unsigned_long_long_type, | ||
| 659 | n), | ||
| 660 | gcc_jit_context_new_rvalue_from_int ( | ||
| 661 | comp.ctxt, | ||
| 662 | comp.unsigned_long_long_type, | ||
| 663 | 32)), | ||
| 664 | gcc_jit_context_new_rvalue_from_int ( | ||
| 665 | comp.ctxt, | ||
| 666 | comp.unsigned_long_long_type, | ||
| 667 | 32)); | ||
| 668 | |||
| 669 | return | ||
| 670 | emit_cast (comp.long_long_type, | ||
| 671 | gcc_jit_context_new_binary_op ( | ||
| 672 | comp.ctxt, | ||
| 673 | NULL, | ||
| 674 | GCC_JIT_BINARY_OP_BITWISE_OR, | ||
| 675 | comp.unsigned_long_long_type, | ||
| 676 | gcc_jit_context_new_binary_op ( | ||
| 677 | comp.ctxt, | ||
| 678 | NULL, | ||
| 679 | GCC_JIT_BINARY_OP_LSHIFT, | ||
| 680 | comp.unsigned_long_long_type, | ||
| 681 | high, | ||
| 682 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 683 | comp.unsigned_long_long_type, | ||
| 684 | 32)), | ||
| 685 | low)); | ||
| 686 | } | ||
| 687 | |||
| 688 | static gcc_jit_rvalue * | ||
| 689 | emit_most_positive_fixnum (void) | ||
| 690 | { | ||
| 691 | #if EMACS_INT_MAX > LONG_MAX | ||
| 692 | return emit_rvalue_from_long_long (MOST_POSITIVE_FIXNUM); | ||
| 693 | #else | ||
| 694 | return gcc_jit_context_new_rvalue_from_long (comp.ctxt, | ||
| 695 | comp.emacs_int_type, | ||
| 696 | MOST_POSITIVE_FIXNUM); | ||
| 697 | #endif | ||
| 698 | } | ||
| 699 | |||
| 700 | static gcc_jit_rvalue * | ||
| 701 | emit_most_negative_fixnum (void) | ||
| 702 | { | ||
| 703 | #if EMACS_INT_MAX > LONG_MAX | ||
| 704 | return emit_rvalue_from_long_long (MOST_NEGATIVE_FIXNUM); | ||
| 705 | #else | ||
| 706 | return gcc_jit_context_new_rvalue_from_long (comp.ctxt, | ||
| 707 | comp.emacs_int_type, | ||
| 708 | MOST_NEGATIVE_FIXNUM); | ||
| 709 | #endif | ||
| 710 | } | ||
| 711 | |||
| 634 | /* | 712 | /* |
| 635 | Emit the equivalent of: | 713 | Emit the equivalent of: |
| 636 | (typeof_ptr) ((uintptr) ptr + size_of_ptr_ref * i) | 714 | (typeof_ptr) ((uintptr) ptr + size_of_ptr_ref * i) |
| @@ -700,22 +778,38 @@ emit_lval_XLP (gcc_jit_lvalue *obj) | |||
| 700 | comp.lisp_obj_as_ptr); | 778 | comp.lisp_obj_as_ptr); |
| 701 | } */ | 779 | } */ |
| 702 | static gcc_jit_rvalue * | 780 | static gcc_jit_rvalue * |
| 703 | emit_XUNTAG (gcc_jit_rvalue *a, gcc_jit_type *type, ptrdiff_t lisp_word_tag) | 781 | emit_XUNTAG (gcc_jit_rvalue *a, gcc_jit_type *type, long long lisp_word_tag) |
| 704 | { | 782 | { |
| 705 | /* #define XUNTAG(a, type, ctype) ((ctype *) | 783 | /* #define XUNTAG(a, type, ctype) ((ctype *) |
| 706 | ((char *) XLP (a) - LISP_WORD_TAG (type))) */ | 784 | ((char *) XLP (a) - LISP_WORD_TAG (type))) */ |
| 707 | emit_comment ("XUNTAG"); | 785 | emit_comment ("XUNTAG"); |
| 708 | 786 | ||
| 709 | return emit_cast (gcc_jit_type_get_pointer (type), | 787 | #ifndef WIDE_EMACS_INT |
| 788 | return emit_cast ( | ||
| 789 | gcc_jit_type_get_pointer (type), | ||
| 710 | gcc_jit_context_new_binary_op ( | 790 | gcc_jit_context_new_binary_op ( |
| 711 | comp.ctxt, | 791 | comp.ctxt, |
| 712 | NULL, | 792 | NULL, |
| 713 | GCC_JIT_BINARY_OP_MINUS, | 793 | GCC_JIT_BINARY_OP_MINUS, |
| 714 | comp.emacs_int_type, | 794 | comp.emacs_int_type, |
| 715 | emit_XLI (a), | 795 | emit_XLI (a), |
| 716 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 796 | gcc_jit_context_new_rvalue_from_int ( |
| 717 | comp.emacs_int_type, | 797 | comp.ctxt, |
| 718 | lisp_word_tag))); | 798 | comp.emacs_int_type, |
| 799 | lisp_word_tag))); | ||
| 800 | #else | ||
| 801 | return emit_cast ( | ||
| 802 | gcc_jit_type_get_pointer (type), | ||
| 803 | gcc_jit_context_new_binary_op ( | ||
| 804 | comp.ctxt, | ||
| 805 | NULL, | ||
| 806 | GCC_JIT_BINARY_OP_MINUS, | ||
| 807 | comp.unsigned_long_long_type, | ||
| 808 | /* FIXME Should be XLP. */ | ||
| 809 | emit_cast (comp.unsigned_long_long_type, emit_XLI (a)), | ||
| 810 | emit_cast (comp.unsigned_long_long_type, | ||
| 811 | emit_rvalue_from_long_long (lisp_word_tag)))); | ||
| 812 | #endif | ||
| 719 | } | 813 | } |
| 720 | 814 | ||
| 721 | static gcc_jit_rvalue * | 815 | static gcc_jit_rvalue * |
| @@ -886,13 +980,31 @@ static gcc_jit_rvalue * | |||
| 886 | emit_XFIXNUM (gcc_jit_rvalue *obj) | 980 | emit_XFIXNUM (gcc_jit_rvalue *obj) |
| 887 | { | 981 | { |
| 888 | emit_comment ("XFIXNUM"); | 982 | emit_comment ("XFIXNUM"); |
| 983 | gcc_jit_rvalue *i = emit_cast (comp.emacs_uint_type, emit_XLI (obj)); | ||
| 889 | 984 | ||
| 890 | return gcc_jit_context_new_binary_op (comp.ctxt, | 985 | if (!USE_LSB_TAG) |
| 891 | NULL, | 986 | { |
| 892 | GCC_JIT_BINARY_OP_RSHIFT, | 987 | i = gcc_jit_context_new_binary_op (comp.ctxt, |
| 893 | comp.emacs_int_type, | 988 | NULL, |
| 894 | emit_XLI (obj), | 989 | GCC_JIT_BINARY_OP_LSHIFT, |
| 895 | comp.inttypebits); | 990 | comp.emacs_uint_type, |
| 991 | emit_cast (comp.emacs_uint_type, i), | ||
| 992 | comp.inttypebits); | ||
| 993 | |||
| 994 | return gcc_jit_context_new_binary_op (comp.ctxt, | ||
| 995 | NULL, | ||
| 996 | GCC_JIT_BINARY_OP_RSHIFT, | ||
| 997 | comp.emacs_int_type, | ||
| 998 | i, | ||
| 999 | comp.inttypebits); | ||
| 1000 | } | ||
| 1001 | else | ||
| 1002 | return gcc_jit_context_new_binary_op (comp.ctxt, | ||
| 1003 | NULL, | ||
| 1004 | GCC_JIT_BINARY_OP_LSHIFT, | ||
| 1005 | comp.emacs_int_type, | ||
| 1006 | i, | ||
| 1007 | comp.inttypebits); | ||
| 896 | } | 1008 | } |
| 897 | 1009 | ||
| 898 | static gcc_jit_rvalue * | 1010 | static gcc_jit_rvalue * |
| @@ -924,16 +1036,20 @@ emit_NUMBERP (gcc_jit_rvalue *obj) | |||
| 924 | } | 1036 | } |
| 925 | 1037 | ||
| 926 | static gcc_jit_rvalue * | 1038 | static gcc_jit_rvalue * |
| 927 | emit_make_fixnum (gcc_jit_rvalue *obj) | 1039 | emit_make_fixnum_LSB_TAG (gcc_jit_rvalue *n) |
| 928 | { | 1040 | { |
| 929 | emit_comment ("make_fixnum"); | 1041 | /* |
| 1042 | EMACS_UINT u = n; | ||
| 1043 | n = u << INTTYPEBITS; | ||
| 1044 | n += int0; | ||
| 1045 | */ | ||
| 930 | 1046 | ||
| 931 | gcc_jit_rvalue *tmp = | 1047 | gcc_jit_rvalue *tmp = |
| 932 | gcc_jit_context_new_binary_op (comp.ctxt, | 1048 | gcc_jit_context_new_binary_op (comp.ctxt, |
| 933 | NULL, | 1049 | NULL, |
| 934 | GCC_JIT_BINARY_OP_LSHIFT, | 1050 | GCC_JIT_BINARY_OP_LSHIFT, |
| 935 | comp.emacs_int_type, | 1051 | comp.emacs_int_type, |
| 936 | obj, | 1052 | emit_cast (comp.emacs_uint_type, n), |
| 937 | comp.inttypebits); | 1053 | comp.inttypebits); |
| 938 | 1054 | ||
| 939 | tmp = gcc_jit_context_new_binary_op (comp.ctxt, | 1055 | tmp = gcc_jit_context_new_binary_op (comp.ctxt, |
| @@ -957,6 +1073,55 @@ emit_make_fixnum (gcc_jit_rvalue *obj) | |||
| 957 | } | 1073 | } |
| 958 | 1074 | ||
| 959 | static gcc_jit_rvalue * | 1075 | static gcc_jit_rvalue * |
| 1076 | emit_make_fixnum_MSB_TAG (gcc_jit_rvalue *n) | ||
| 1077 | { | ||
| 1078 | /* | ||
| 1079 | n &= INTMASK; | ||
| 1080 | n += (int0 << VALBITS); | ||
| 1081 | return XIL (n); | ||
| 1082 | */ | ||
| 1083 | |||
| 1084 | gcc_jit_rvalue *intmask = | ||
| 1085 | emit_cast (comp.emacs_uint_type, | ||
| 1086 | emit_rvalue_from_long_long ((EMACS_INT_MAX | ||
| 1087 | >> (INTTYPEBITS - 1)))); | ||
| 1088 | n = gcc_jit_context_new_binary_op ( | ||
| 1089 | comp.ctxt, | ||
| 1090 | NULL, | ||
| 1091 | GCC_JIT_BINARY_OP_BITWISE_AND, | ||
| 1092 | comp.emacs_uint_type, | ||
| 1093 | intmask, | ||
| 1094 | emit_cast (comp.emacs_uint_type, n)); | ||
| 1095 | |||
| 1096 | n = gcc_jit_context_new_binary_op ( | ||
| 1097 | comp.ctxt, | ||
| 1098 | NULL, | ||
| 1099 | GCC_JIT_BINARY_OP_PLUS, | ||
| 1100 | comp.emacs_uint_type, | ||
| 1101 | gcc_jit_context_new_binary_op ( | ||
| 1102 | comp.ctxt, | ||
| 1103 | NULL, | ||
| 1104 | GCC_JIT_BINARY_OP_LSHIFT, | ||
| 1105 | comp.emacs_uint_type, | ||
| 1106 | emit_cast (comp.emacs_uint_type, comp.lisp_int0), | ||
| 1107 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1108 | comp.emacs_uint_type, | ||
| 1109 | VALBITS)), | ||
| 1110 | n); | ||
| 1111 | return emit_XLI (emit_cast (comp.emacs_int_type, n)); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | |||
| 1115 | static gcc_jit_rvalue * | ||
| 1116 | emit_make_fixnum (gcc_jit_rvalue *obj) | ||
| 1117 | { | ||
| 1118 | emit_comment ("make_fixnum"); | ||
| 1119 | return USE_LSB_TAG | ||
| 1120 | ? emit_make_fixnum_LSB_TAG (obj) | ||
| 1121 | : emit_make_fixnum_MSB_TAG (obj); | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | static gcc_jit_rvalue * | ||
| 960 | emit_const_lisp_obj (Lisp_Object obj) | 1125 | emit_const_lisp_obj (Lisp_Object obj) |
| 961 | { | 1126 | { |
| 962 | emit_comment (format_string ("const lisp obj: %s", | 1127 | emit_comment (format_string ("const lisp obj: %s", |
| @@ -1188,9 +1353,11 @@ emit_mvar_val (Lisp_Object mvar) | |||
| 1188 | word (read fixnums). */ | 1353 | word (read fixnums). */ |
| 1189 | emit_comment (SSDATA (Fprin1_to_string (constant, Qnil))); | 1354 | emit_comment (SSDATA (Fprin1_to_string (constant, Qnil))); |
| 1190 | gcc_jit_rvalue *word = | 1355 | gcc_jit_rvalue *word = |
| 1191 | gcc_jit_context_new_rvalue_from_ptr (comp.ctxt, | 1356 | (sizeof (MOST_POSITIVE_FIXNUM) > sizeof (void *)) |
| 1192 | comp.void_ptr_type, | 1357 | ? emit_rvalue_from_long_long (constant) |
| 1193 | constant); | 1358 | : gcc_jit_context_new_rvalue_from_long (comp.ctxt, |
| 1359 | comp.void_ptr_type, | ||
| 1360 | constant); | ||
| 1194 | return emit_cast (comp.lisp_obj_type, word); | 1361 | return emit_cast (comp.lisp_obj_type, word); |
| 1195 | } | 1362 | } |
| 1196 | /* Other const objects are fetched from the reloc array. */ | 1363 | /* Other const objects are fetched from the reloc array. */ |
| @@ -2574,8 +2741,6 @@ define_add1_sub1 (void) | |||
| 2574 | gcc_jit_function *func[2]; | 2741 | gcc_jit_function *func[2]; |
| 2575 | char const *f_name[] = { "add1", "sub1" }; | 2742 | char const *f_name[] = { "add1", "sub1" }; |
| 2576 | char const *fall_back_func[] = { "1+", "1-" }; | 2743 | char const *fall_back_func[] = { "1+", "1-" }; |
| 2577 | gcc_jit_rvalue *compare[] = | ||
| 2578 | { comp.most_positive_fixnum, comp.most_negative_fixnum }; | ||
| 2579 | enum gcc_jit_binary_op op[] = | 2744 | enum gcc_jit_binary_op op[] = |
| 2580 | { GCC_JIT_BINARY_OP_PLUS, GCC_JIT_BINARY_OP_MINUS }; | 2745 | { GCC_JIT_BINARY_OP_PLUS, GCC_JIT_BINARY_OP_MINUS }; |
| 2581 | for (ptrdiff_t i = 0; i < 2; i++) | 2746 | for (ptrdiff_t i = 0; i < 2; i++) |
| @@ -2630,7 +2795,9 @@ define_add1_sub1 (void) | |||
| 2630 | NULL, | 2795 | NULL, |
| 2631 | GCC_JIT_COMPARISON_NE, | 2796 | GCC_JIT_COMPARISON_NE, |
| 2632 | n_fixnum, | 2797 | n_fixnum, |
| 2633 | compare[i])), | 2798 | i == 0 |
| 2799 | ? emit_most_positive_fixnum () | ||
| 2800 | : emit_most_negative_fixnum ())), | ||
| 2634 | inline_block, | 2801 | inline_block, |
| 2635 | fcall_block); | 2802 | fcall_block); |
| 2636 | 2803 | ||
| @@ -2712,7 +2879,7 @@ define_negate (void) | |||
| 2712 | NULL, | 2879 | NULL, |
| 2713 | GCC_JIT_COMPARISON_NE, | 2880 | GCC_JIT_COMPARISON_NE, |
| 2714 | n_fixnum, | 2881 | n_fixnum, |
| 2715 | comp.most_negative_fixnum)), | 2882 | emit_most_negative_fixnum ())), |
| 2716 | inline_block, | 2883 | inline_block, |
| 2717 | fcall_block); | 2884 | fcall_block); |
| 2718 | 2885 | ||
| @@ -3127,25 +3294,20 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt, | |||
| 3127 | comp.emacs_int_type = gcc_jit_context_get_int_type (comp.ctxt, | 3294 | comp.emacs_int_type = gcc_jit_context_get_int_type (comp.ctxt, |
| 3128 | sizeof (EMACS_INT), | 3295 | sizeof (EMACS_INT), |
| 3129 | true); | 3296 | true); |
| 3297 | comp.emacs_uint_type = gcc_jit_context_get_int_type (comp.ctxt, | ||
| 3298 | sizeof (EMACS_UINT), | ||
| 3299 | false); | ||
| 3130 | /* No XLP is emitted for now so lets define this always as integer | 3300 | /* No XLP is emitted for now so lets define this always as integer |
| 3131 | disregarding LISP_WORDS_ARE_POINTERS value. */ | 3301 | disregarding LISP_WORDS_ARE_POINTERS value. */ |
| 3132 | comp.lisp_obj_type = comp.emacs_int_type; | 3302 | comp.lisp_obj_type = comp.emacs_int_type; |
| 3133 | comp.lisp_obj_ptr_type = gcc_jit_type_get_pointer (comp.lisp_obj_type); | 3303 | comp.lisp_obj_ptr_type = gcc_jit_type_get_pointer (comp.lisp_obj_type); |
| 3134 | comp.most_positive_fixnum = | ||
| 3135 | gcc_jit_context_new_rvalue_from_long (comp.ctxt, | ||
| 3136 | comp.emacs_int_type, | ||
| 3137 | MOST_POSITIVE_FIXNUM); | ||
| 3138 | comp.most_negative_fixnum = | ||
| 3139 | gcc_jit_context_new_rvalue_from_long (comp.ctxt, | ||
| 3140 | comp.emacs_int_type, | ||
| 3141 | MOST_NEGATIVE_FIXNUM); | ||
| 3142 | comp.one = | 3304 | comp.one = |
| 3143 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 3305 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, |
| 3144 | comp.emacs_int_type, | 3306 | comp.emacs_int_type, |
| 3145 | 1); | 3307 | 1); |
| 3146 | comp.inttypebits = | 3308 | comp.inttypebits = |
| 3147 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 3309 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, |
| 3148 | comp.emacs_int_type, | 3310 | comp.emacs_uint_type, |
| 3149 | INTTYPEBITS); | 3311 | INTTYPEBITS); |
| 3150 | comp.lisp_int0 = | 3312 | comp.lisp_int0 = |
| 3151 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 3313 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, |