aboutsummaryrefslogtreecommitdiffstats
path: root/src/comp.c
diff options
context:
space:
mode:
authorAndreas Schwab2021-08-30 18:26:46 +0200
committerAndreas Schwab2021-08-30 19:00:46 +0200
commit6767e556590b10a168300a8746589cf401bc93eb (patch)
tree24d9920e44d9b97fbe96ae9a8acbeaa6f9019f09 /src/comp.c
parentebd7c52f1169fb61a5f9a4a02959e5eedba79d86 (diff)
downloademacs-6767e556590b10a168300a8746589cf401bc93eb.tar.gz
emacs-6767e556590b10a168300a8746589cf401bc93eb.zip
Implement proper type conversion in native compiler
* src/comp.c (enum cast_kind_of_type): Remove. (comp_t): Add cast_ptr_to_int, cast_int_to_ptr, remove cast_type_sizes, cast_type_kind, cast_type_names, cast_union_fields, cast_union_field_biggest_type. (emit_coerce): Remove check for type size. (struct cast_type): Remove bytes_size. (define_type_punning): New function. (define_cast_from_to): Implement proper type conversion. (define_cast_functions): Adjust. (bug#50230)
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c210
1 files changed, 102 insertions, 108 deletions
diff --git a/src/comp.c b/src/comp.c
index 74a5337f8d7..3ea2836560f 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -499,13 +499,6 @@ static f_reloc_t freloc;
499 499
500#define NUM_CAST_TYPES 15 500#define NUM_CAST_TYPES 15
501 501
502enum cast_kind_of_type
503 {
504 kind_unsigned,
505 kind_signed,
506 kind_pointer
507 };
508
509typedef struct { 502typedef struct {
510 EMACS_INT len; 503 EMACS_INT len;
511 gcc_jit_rvalue *r_val; 504 gcc_jit_rvalue *r_val;
@@ -571,14 +564,9 @@ typedef struct {
571 be used for the scope. */ 564 be used for the scope. */
572 gcc_jit_type *cast_union_type; 565 gcc_jit_type *cast_union_type;
573 gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES]; 566 gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES];
574 /* We add one to make space for the last member which is the "biggest_type" 567 gcc_jit_function *cast_ptr_to_int;
575 member. */ 568 gcc_jit_function *cast_int_to_ptr;
576 gcc_jit_type *cast_types[NUM_CAST_TYPES + 1]; 569 gcc_jit_type *cast_types[NUM_CAST_TYPES];
577 size_t cast_type_sizes[NUM_CAST_TYPES + 1];
578 enum cast_kind_of_type cast_type_kind[NUM_CAST_TYPES + 1];
579 const char *cast_type_names[NUM_CAST_TYPES + 1];
580 gcc_jit_field *cast_union_fields[NUM_CAST_TYPES + 1];
581 size_t cast_union_field_biggest_type;
582 gcc_jit_function *func; /* Current function being compiled. */ 570 gcc_jit_function *func; /* Current function being compiled. */
583 bool func_has_non_local; /* From comp-func has-non-local slot. */ 571 bool func_has_non_local; /* From comp-func has-non-local slot. */
584 EMACS_INT func_speed; /* From comp-func speed slot. */ 572 EMACS_INT func_speed; /* From comp-func speed slot. */
@@ -1113,13 +1101,6 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
1113 int old_index = type_to_cast_index (old_type); 1101 int old_index = type_to_cast_index (old_type);
1114 int new_index = type_to_cast_index (new_type); 1102 int new_index = type_to_cast_index (new_type);
1115 1103
1116 if (comp.cast_type_sizes[old_index] < comp.cast_type_sizes[new_index]
1117 && comp.cast_type_kind[new_index] == kind_signed)
1118 xsignal3 (Qnative_ice,
1119 build_string ("FIXME: sign extension not implemented"),
1120 build_string (comp.cast_type_names[old_index]),
1121 build_string (comp.cast_type_names[new_index]));
1122
1123 /* Lookup the appropriate cast function in the cast matrix. */ 1104 /* Lookup the appropriate cast function in the cast matrix. */
1124 return gcc_jit_context_new_call (comp.ctxt, 1105 return gcc_jit_context_new_call (comp.ctxt,
1125 NULL, 1106 NULL,
@@ -3111,30 +3092,17 @@ define_thread_state_struct (void)
3111 gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s)); 3092 gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s));
3112} 3093}
3113 3094
3114struct cast_type
3115{
3116 gcc_jit_type *type;
3117 const char *name;
3118 size_t bytes_size;
3119 enum cast_kind_of_type kind;
3120};
3121
3122static gcc_jit_function * 3095static gcc_jit_function *
3123define_cast_from_to (struct cast_type from, int from_index, struct cast_type to, 3096define_type_punning (const char *name,
3124 int to_index) 3097 gcc_jit_type *from, gcc_jit_field *from_field,
3098 gcc_jit_type *to, gcc_jit_field *to_field)
3125{ 3099{
3126 /* FIXME: sign extension not implemented. */
3127 if (comp.cast_type_sizes[from_index] < comp.cast_type_sizes[to_index]
3128 && comp.cast_type_kind[to_index] == kind_signed)
3129 return NULL;
3130
3131 char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
3132 gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL, 3100 gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
3133 from.type, "arg"); 3101 from, "arg");
3134 gcc_jit_function *result = gcc_jit_context_new_function (comp.ctxt, 3102 gcc_jit_function *result = gcc_jit_context_new_function (comp.ctxt,
3135 NULL, 3103 NULL,
3136 GCC_JIT_FUNCTION_INTERNAL, 3104 GCC_JIT_FUNCTION_INTERNAL,
3137 to.type, 3105 to,
3138 name, 3106 name,
3139 1, 3107 1,
3140 &param, 3108 &param,
@@ -3148,26 +3116,63 @@ define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
3148 comp.cast_union_type, 3116 comp.cast_union_type,
3149 "union_cast"); 3117 "union_cast");
3150 3118
3151 /* Zero the union first. */
3152 gcc_jit_block_add_assignment (entry_block, NULL, 3119 gcc_jit_block_add_assignment (entry_block, NULL,
3153 gcc_jit_lvalue_access_field (tmp_union, NULL, 3120 gcc_jit_lvalue_access_field (tmp_union, NULL,
3154 comp.cast_union_fields[NUM_CAST_TYPES]), 3121 from_field),
3155 gcc_jit_context_new_rvalue_from_int (
3156 comp.ctxt,
3157 comp.cast_types[NUM_CAST_TYPES],
3158 0));
3159
3160 gcc_jit_block_add_assignment (entry_block, NULL,
3161 gcc_jit_lvalue_access_field (tmp_union, NULL,
3162 comp.cast_union_fields[from_index]),
3163 gcc_jit_param_as_rvalue (param)); 3122 gcc_jit_param_as_rvalue (param));
3164 3123
3165 gcc_jit_block_end_with_return (entry_block, 3124 gcc_jit_block_end_with_return (entry_block,
3166 NULL, 3125 NULL,
3167 gcc_jit_rvalue_access_field ( 3126 gcc_jit_rvalue_access_field (
3168 gcc_jit_lvalue_as_rvalue (tmp_union), 3127 gcc_jit_lvalue_as_rvalue (tmp_union),
3169 NULL, 3128 NULL, to_field));
3170 comp.cast_union_fields[to_index])); 3129
3130 return result;
3131}
3132
3133struct cast_type
3134{
3135 gcc_jit_type *type;
3136 const char *name;
3137 bool is_ptr;
3138};
3139
3140static gcc_jit_function *
3141define_cast_from_to (struct cast_type from, struct cast_type to)
3142{
3143 char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
3144 gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
3145 from.type, "arg");
3146 gcc_jit_function *result
3147 = gcc_jit_context_new_function (comp.ctxt,
3148 NULL,
3149 GCC_JIT_FUNCTION_INTERNAL,
3150 to.type, name,
3151 1, &param, 0);
3152 DECL_BLOCK (entry_block, result);
3153
3154 gcc_jit_rvalue *tmp = gcc_jit_param_as_rvalue (param);
3155 if (from.is_ptr != to.is_ptr)
3156 {
3157 if (from.is_ptr)
3158 {
3159 tmp = gcc_jit_context_new_cast (comp.ctxt, NULL,
3160 tmp, comp.void_ptr_type);
3161 tmp = gcc_jit_context_new_call (comp.ctxt, NULL,
3162 comp.cast_ptr_to_int, 1, &tmp);
3163 }
3164 else
3165 {
3166 tmp = gcc_jit_context_new_cast (comp.ctxt, NULL,
3167 tmp, comp.uintptr_type);
3168 tmp = gcc_jit_context_new_call (comp.ctxt, NULL,
3169 comp.cast_int_to_ptr, 1, &tmp);
3170 }
3171 }
3172
3173 tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, to.type);
3174
3175 gcc_jit_block_end_with_return (entry_block, NULL, tmp);
3171 3176
3172 return result; 3177 return result;
3173} 3178}
@@ -3176,69 +3181,58 @@ static void
3176define_cast_functions (void) 3181define_cast_functions (void)
3177{ 3182{
3178 struct cast_type cast_types[NUM_CAST_TYPES] 3183 struct cast_type cast_types[NUM_CAST_TYPES]
3179 = { { comp.bool_type, "bool", sizeof (bool), kind_unsigned }, 3184 = { { comp.bool_type, "bool", false },
3180 { comp.char_ptr_type, "char_ptr", sizeof (char *), kind_pointer }, 3185 { comp.char_ptr_type, "char_ptr", true },
3181 { comp.int_type, "int", sizeof (int), kind_signed }, 3186 { comp.int_type, "int", false },
3182 { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *), 3187 { comp.lisp_cons_ptr_type, "lisp_cons_ptr", true },
3183 kind_pointer }, 3188 { comp.lisp_obj_ptr_type, "lisp_obj_ptr", true },
3184 { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *), 3189 { comp.lisp_word_tag_type, "lisp_word_tag", false },
3185 kind_pointer }, 3190 { comp.lisp_word_type, "lisp_word", LISP_WORDS_ARE_POINTERS },
3186 { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag), 3191 { comp.long_long_type, "long_long", false },
3187 kind_unsigned }, 3192 { comp.long_type, "long", false },
3188 { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word), 3193 { comp.ptrdiff_type, "ptrdiff", false },
3189 LISP_WORDS_ARE_POINTERS ? kind_pointer : kind_signed }, 3194 { comp.uintptr_type, "uintptr", false },
3190 { comp.long_long_type, "long_long", sizeof (long long), kind_signed }, 3195 { comp.unsigned_long_long_type, "unsigned_long_long", false },
3191 { comp.long_type, "long", sizeof (long), kind_signed }, 3196 { comp.unsigned_long_type, "unsigned_long", false },
3192 { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t), kind_signed }, 3197 { comp.unsigned_type, "unsigned", false },
3193 { comp.uintptr_type, "uintptr", sizeof (uintptr_t), kind_unsigned }, 3198 { comp.void_ptr_type, "void_ptr", true } };
3194 { comp.unsigned_long_long_type, "unsigned_long_long", 3199 gcc_jit_field *cast_union_fields[2];
3195 sizeof (unsigned long long), kind_unsigned }, 3200
3196 { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long), 3201 /* Define the union used for type punning. */
3197 kind_unsigned }, 3202 cast_union_fields[0] = gcc_jit_context_new_field (comp.ctxt,
3198 { comp.unsigned_type, "unsigned", sizeof (unsigned), kind_unsigned }, 3203 NULL,
3199 { comp.void_ptr_type, "void_ptr", sizeof (void*), kind_pointer } }; 3204 comp.void_ptr_type,
3200 3205 "void_ptr");
3201 /* Find the biggest size. It should be unsigned long long, but to be 3206 cast_union_fields[1] = gcc_jit_context_new_field (comp.ctxt,
3202 sure we find it programmatically. */ 3207 NULL,
3203 size_t biggest_size = 0; 3208 comp.uintptr_type,
3204 for (int i = 0; i < NUM_CAST_TYPES; ++i) 3209 "uintptr");
3205 biggest_size = max (biggest_size, cast_types[i].bytes_size);
3206 3210
3207 /* Define the union used for casting. */ 3211 comp.cast_union_type
3208 for (int i = 0; i < NUM_CAST_TYPES; ++i) 3212 = gcc_jit_context_new_union_type (comp.ctxt,
3209 { 3213 NULL,
3210 comp.cast_types[i] = cast_types[i].type; 3214 "cast_union",
3211 comp.cast_union_fields[i] = gcc_jit_context_new_field (comp.ctxt, 3215 2, cast_union_fields);
3212 NULL, 3216
3213 cast_types[i].type, 3217 comp.cast_ptr_to_int = define_type_punning ("cast_pointer_to_uintptr_t",
3214 cast_types[i].name); 3218 comp.void_ptr_type,
3215 comp.cast_type_names[i] = cast_types[i].name; 3219 cast_union_fields[0],
3216 comp.cast_type_sizes[i] = cast_types[i].bytes_size; 3220 comp.uintptr_type,
3217 comp.cast_type_kind[i] = cast_types[i].kind; 3221 cast_union_fields[1]);
3218 } 3222 comp.cast_int_to_ptr = define_type_punning ("cast_uintptr_t_to_pointer",
3223 comp.uintptr_type,
3224 cast_union_fields[1],
3225 comp.void_ptr_type,
3226 cast_union_fields[0]);
3219 3227
3220 gcc_jit_type *biggest_type = gcc_jit_context_get_int_type (comp.ctxt, 3228 for (int i = 0; i < NUM_CAST_TYPES; ++i)
3221 biggest_size, 3229 comp.cast_types[i] = cast_types[i].type;
3222 false);
3223 comp.cast_types[NUM_CAST_TYPES] = biggest_type;
3224 comp.cast_union_fields[NUM_CAST_TYPES] =
3225 gcc_jit_context_new_field (comp.ctxt, NULL, biggest_type, "biggest_type");
3226 comp.cast_type_names[NUM_CAST_TYPES] = "biggest_type";
3227 comp.cast_type_sizes[NUM_CAST_TYPES] = biggest_size;
3228 comp.cast_type_kind[NUM_CAST_TYPES] = kind_unsigned;
3229
3230 comp.cast_union_type =
3231 gcc_jit_context_new_union_type (comp.ctxt,
3232 NULL,
3233 "cast_union",
3234 NUM_CAST_TYPES + 1,
3235 comp.cast_union_fields);
3236 3230
3237 /* Define the cast functions using a matrix. */ 3231 /* Define the cast functions using a matrix. */
3238 for (int i = 0; i < NUM_CAST_TYPES; ++i) 3232 for (int i = 0; i < NUM_CAST_TYPES; ++i)
3239 for (int j = 0; j < NUM_CAST_TYPES; ++j) 3233 for (int j = 0; j < NUM_CAST_TYPES; ++j)
3240 comp.cast_functions_from_to[i][j] = 3234 comp.cast_functions_from_to[i][j] =
3241 define_cast_from_to (cast_types[i], i, cast_types[j], j); 3235 define_cast_from_to (cast_types[i], cast_types[j]);
3242} 3236}
3243 3237
3244static void 3238static void