aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2019-06-09 17:01:06 +0200
committerAndrea Corallo2020-01-01 11:33:40 +0100
commit8bfe8ce8d0885e8022b2bea82d1cff9cbed86fb1 (patch)
treef896aa9c8056aacacdb6d394e2de9923e955cf14 /src
parent96fc40d7dbdc77efa7b2e01f231bef9e19e96786 (diff)
downloademacs-8bfe8ce8d0885e8022b2bea82d1cff9cbed86fb1.tar.gz
emacs-8bfe8ce8d0885e8022b2bea82d1cff9cbed86fb1.zip
add sub1
Diffstat (limited to 'src')
-rw-r--r--src/comp.c287
1 files changed, 224 insertions, 63 deletions
diff --git a/src/comp.c b/src/comp.c
index 63bf88870bd..0098b814581 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -149,7 +149,9 @@ typedef struct {
149typedef struct { 149typedef struct {
150 gcc_jit_context *ctxt; 150 gcc_jit_context *ctxt;
151 gcc_jit_type *void_type; 151 gcc_jit_type *void_type;
152 gcc_jit_type *bool_type;
152 gcc_jit_type *int_type; 153 gcc_jit_type *int_type;
154 gcc_jit_type *unsigned_type;
153 gcc_jit_type *long_type; 155 gcc_jit_type *long_type;
154 gcc_jit_type *long_long_type; 156 gcc_jit_type *long_long_type;
155 gcc_jit_type *void_ptr_type; 157 gcc_jit_type *void_ptr_type;
@@ -157,6 +159,13 @@ typedef struct {
157 gcc_jit_type *lisp_obj_type; 159 gcc_jit_type *lisp_obj_type;
158 gcc_jit_field *lisp_obj_as_ptr; 160 gcc_jit_field *lisp_obj_as_ptr;
159 gcc_jit_field *lisp_obj_as_num; 161 gcc_jit_field *lisp_obj_as_num;
162 /* libgccjit has really limited support for casting therefore this union will
163 be used for the scope. */
164 gcc_jit_type *cast_union_type;
165 gcc_jit_field *cast_union_as_ll;
166 gcc_jit_field *cast_union_as_u;
167 gcc_jit_field *cast_union_as_i;
168 gcc_jit_field *cast_union_as_b;
160 gcc_jit_function *func; /* Current function being compiled */ 169 gcc_jit_function *func; /* Current function being compiled */
161 gcc_jit_rvalue *scratch; /* Will point to scratch_call_area */ 170 gcc_jit_rvalue *scratch; /* Will point to scratch_call_area */
162 gcc_jit_rvalue *most_positive_fixnum; 171 gcc_jit_rvalue *most_positive_fixnum;
@@ -211,22 +220,118 @@ pop (unsigned n, gcc_jit_lvalue ***stack_ref, gcc_jit_rvalue *args[])
211 *stack_ref = stack; 220 *stack_ref = stack;
212} 221}
213 222
223INLINE static gcc_jit_field *
224type_to_cast_field (gcc_jit_type *type)
225{
226 gcc_jit_field *field;
227
228 if (type == comp.long_long_type)
229 field = comp.cast_union_as_ll;
230 else if (type == comp.unsigned_type)
231 field = comp.cast_union_as_u;
232 else if (type == comp.int_type)
233 field = comp.cast_union_as_i;
234 else if (type == comp.bool_type)
235 field = comp.cast_union_as_b;
236 else
237 error ("unsopported cast\n");
238
239 return field;
240}
241
242static gcc_jit_rvalue *
243comp_cast (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
244{
245 gcc_jit_field *orig_field =
246 type_to_cast_field (gcc_jit_rvalue_get_type (obj));
247 gcc_jit_field *dest_field = type_to_cast_field (new_type);
248
249 gcc_jit_lvalue *tmp_u =
250 gcc_jit_function_new_local (comp.func,
251 NULL,
252 comp.cast_union_type,
253 "union_cast");
254 gcc_jit_block_add_assignment (comp.bblock->gcc_bb,
255 NULL,
256 gcc_jit_lvalue_access_field (tmp_u,
257 NULL,
258 orig_field),
259 obj);
260
261 return gcc_jit_rvalue_access_field ( gcc_jit_lvalue_as_rvalue (tmp_u),
262 NULL,
263 dest_field);
264}
265
214INLINE static gcc_jit_rvalue * 266INLINE static gcc_jit_rvalue *
215comp_xfixnum (gcc_jit_rvalue *obj) 267comp_XLI (gcc_jit_rvalue *obj)
268{
269 return gcc_jit_rvalue_access_field (obj,
270 NULL,
271 comp.lisp_obj_as_num);
272}
273
274static gcc_jit_rvalue *
275comp_FIXNUMP (gcc_jit_rvalue *obj)
216{ 276{
217 return gcc_jit_context_new_binary_op ( 277 /* (! (((unsigned) (XLI (x) >> (USE_LSB_TAG ? 0 : FIXNUM_BITS))
218 comp.ctxt, 278 - (unsigned) (Lisp_Int0 >> !USE_LSB_TAG))
219 NULL, 279 & ((1 << INTTYPEBITS) - 1))) */
220 GCC_JIT_BINARY_OP_RSHIFT, 280
221 comp.long_long_type, 281 gcc_jit_rvalue *sh_res =
222 gcc_jit_rvalue_access_field (obj, 282 gcc_jit_context_new_binary_op (
283 comp.ctxt,
284 NULL,
285 GCC_JIT_BINARY_OP_RSHIFT,
286 comp.long_long_type,
287 comp_XLI (obj),
288 gcc_jit_context_new_rvalue_from_int (comp.ctxt,
289 comp.long_long_type,
290 (USE_LSB_TAG ? 0 : FIXNUM_BITS)));
291
292 gcc_jit_rvalue *minus_res =
293 gcc_jit_context_new_binary_op (comp.ctxt,
294 NULL,
295 GCC_JIT_BINARY_OP_MINUS,
296 comp.unsigned_type,
297 comp_cast (comp.unsigned_type, sh_res),
298 gcc_jit_context_new_rvalue_from_int (
299 comp.ctxt,
300 comp.unsigned_type,
301 (Lisp_Int0 >> !USE_LSB_TAG)));
302
303 gcc_jit_rvalue *res =
304 gcc_jit_context_new_unary_op (
305 comp.ctxt,
306 NULL,
307 GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
308 comp.int_type,
309 gcc_jit_context_new_binary_op (comp.ctxt,
310 NULL,
311 GCC_JIT_BINARY_OP_BITWISE_AND,
312 comp.unsigned_type,
313 minus_res,
314 gcc_jit_context_new_rvalue_from_int (
315 comp.ctxt,
316 comp.unsigned_type,
317 ((1 << INTTYPEBITS) - 1))));
318
319 return res;
320}
321
322static gcc_jit_rvalue *
323comp_XFIXNUM (gcc_jit_rvalue *obj)
324{
325 return gcc_jit_context_new_binary_op (comp.ctxt,
223 NULL, 326 NULL,
224 comp.lisp_obj_as_num), 327 GCC_JIT_BINARY_OP_RSHIFT,
225 comp.inttypebits); 328 comp.long_long_type,
329 comp_XLI (obj),
330 comp.inttypebits);
226} 331}
227 332
228INLINE static gcc_jit_rvalue * 333static gcc_jit_rvalue *
229comp_make_fixnum (gcc_jit_rvalue *obj) 334comp_make_fixnum (gcc_jit_block *block, gcc_jit_rvalue *obj)
230{ 335{
231 gcc_jit_rvalue *tmp = 336 gcc_jit_rvalue *tmp =
232 gcc_jit_context_new_binary_op (comp.ctxt, 337 gcc_jit_context_new_binary_op (comp.ctxt,
@@ -248,7 +353,7 @@ comp_make_fixnum (gcc_jit_rvalue *obj)
248 comp.lisp_obj_type, 353 comp.lisp_obj_type,
249 "lisp_obj_fixnum"); 354 "lisp_obj_fixnum");
250 355
251 gcc_jit_block_add_assignment (comp.bblock->gcc_bb, 356 gcc_jit_block_add_assignment (block,
252 NULL, 357 NULL,
253 gcc_jit_lvalue_access_field ( 358 gcc_jit_lvalue_access_field (
254 res, 359 res,
@@ -261,7 +366,7 @@ comp_make_fixnum (gcc_jit_rvalue *obj)
261 366
262/* Construct fill and return a lisp object form a raw pointer. */ 367/* Construct fill and return a lisp object form a raw pointer. */
263 368
264INLINE static gcc_jit_rvalue * 369static gcc_jit_rvalue *
265comp_lisp_obj_as_ptr_from_ptr (basic_block_t *bblock, void *p) 370comp_lisp_obj_as_ptr_from_ptr (basic_block_t *bblock, void *p)
266{ 371{
267 gcc_jit_lvalue *lisp_obj = gcc_jit_function_new_local (comp.func, 372 gcc_jit_lvalue *lisp_obj = gcc_jit_function_new_local (comp.func,
@@ -567,9 +672,8 @@ compute_bblocks (ptrdiff_t bytestr_length, unsigned char *bytestr_data)
567 672
568/* Close current basic block emitting a conditional. */ 673/* Close current basic block emitting a conditional. */
569 674
570static void 675INLINE static void
571comp_emit_conditional (enum gcc_jit_comparison op, 676comp_emit_cond_jump (gcc_jit_rvalue *test,
572 gcc_jit_rvalue *test,
573 gcc_jit_block *then_target, gcc_jit_block *else_target) 677 gcc_jit_block *then_target, gcc_jit_block *else_target)
574{ 678{
575 gcc_jit_block_end_with_conditional (comp.bblock->gcc_bb, 679 gcc_jit_block_end_with_conditional (comp.bblock->gcc_bb,
@@ -583,16 +687,16 @@ comp_emit_conditional (enum gcc_jit_comparison op,
583/* Close current basic block emitting a comparison between two rval. */ 687/* Close current basic block emitting a comparison between two rval. */
584 688
585static gcc_jit_rvalue * 689static gcc_jit_rvalue *
586comp_emit_comparison (enum gcc_jit_comparison op, 690comp_emit_comp_jump (enum gcc_jit_comparison op,
587 gcc_jit_rvalue *a, gcc_jit_rvalue *b, 691 gcc_jit_rvalue *a, gcc_jit_rvalue *b,
588 gcc_jit_block *then_target, gcc_jit_block *else_target) 692 gcc_jit_block *then_target, gcc_jit_block *else_target)
589{ 693{
590 gcc_jit_rvalue *test = gcc_jit_context_new_comparison (comp.ctxt, 694 gcc_jit_rvalue *test = gcc_jit_context_new_comparison (comp.ctxt,
591 NULL, 695 NULL,
592 op, 696 op,
593 a, b); 697 a, b);
594 698
595 comp_emit_conditional (op, test, then_target, else_target); 699 comp_emit_cond_jump (test, then_target, else_target);
596 700
597 return test; 701 return test;
598} 702}
@@ -892,38 +996,60 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length,
892 996
893 case Bsub1: 997 case Bsub1:
894 { 998 {
895 gcc_jit_block *sub1_inline = 999
896 gcc_jit_function_new_block (comp.func, "-1 inline"); 1000 /* (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM
897 gcc_jit_block *sub1_fcall = 1001 ? make_fixnum (XFIXNUM (TOP) - 1)
898 gcc_jit_function_new_block (comp.func, "-1 fcall"); 1002 : Fsub1 (TOP)) */
1003
1004 gcc_jit_block *sub1_inline_block =
1005 gcc_jit_function_new_block (comp.func, "inline-1");
1006 gcc_jit_block *sub1_fcall_block =
1007 gcc_jit_function_new_block (comp.func, "fcall-1");
899 1008
900 gcc_jit_rvalue *tos_as_num = 1009 gcc_jit_rvalue *tos_as_num =
901 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (TOS), 1010 comp_XFIXNUM (gcc_jit_lvalue_as_rvalue (TOS));
902 NULL, 1011
903 comp.lisp_obj_as_num); 1012 comp_emit_cond_jump (
904 comp_emit_comparison (GCC_JIT_COMPARISON_NE, 1013 gcc_jit_context_new_binary_op (
905 tos_as_num, 1014 comp.ctxt,
906 comp.most_negative_fixnum, 1015 NULL,
907 sub1_inline, sub1_fcall); 1016 GCC_JIT_BINARY_OP_LOGICAL_AND,
1017 comp.bool_type,
1018 comp_cast (comp.bool_type,
1019 comp_FIXNUMP (gcc_jit_lvalue_as_rvalue (TOS))),
1020 gcc_jit_context_new_comparison (comp.ctxt,
1021 NULL,
1022 GCC_JIT_COMPARISON_NE,
1023 tos_as_num,
1024 comp.most_negative_fixnum)),
1025 sub1_inline_block,
1026 sub1_fcall_block);
1027
908 gcc_jit_rvalue *sub1_inline_res = 1028 gcc_jit_rvalue *sub1_inline_res =
909 gcc_jit_context_new_binary_op (comp.ctxt, 1029 gcc_jit_context_new_binary_op (comp.ctxt,
910 NULL, 1030 NULL,
911 GCC_JIT_BINARY_OP_MINUS, 1031 GCC_JIT_BINARY_OP_MINUS,
912 comp.lisp_obj_type, 1032 comp.long_long_type,
913 tos_as_num, 1033 tos_as_num,
914 comp.one); 1034 comp.one);
915 gcc_jit_block_add_assignment (sub1_inline, 1035
1036 gcc_jit_block_add_assignment (sub1_inline_block,
916 NULL, 1037 NULL,
917 TOS, 1038 TOS,
918 sub1_inline_res); 1039 comp_make_fixnum (sub1_inline_block,
1040 sub1_inline_res));
1041 basic_block_t bb_orig = *comp.bblock;
1042
1043 comp.bblock->gcc_bb = sub1_fcall_block;
1044 POP1;
1045 res = comp_emit_call ("Fsub1", comp.lisp_obj_type, 1, args);
1046 PUSH_LVAL (res);
919 1047
920 /* TODO fill sub1_fcall */ 1048 *comp.bblock = bb_orig;
921 /* comp.bblock->gcc_bb = sub1_fcall; */
922 /* comp.bblock->terminated = false; */
923 1049
924 gcc_jit_block_end_with_jump (sub1_inline, NULL, 1050 gcc_jit_block_end_with_jump (sub1_inline_block, NULL,
925 bb_map[pc].gcc_bb); 1051 bb_map[pc].gcc_bb);
926 gcc_jit_block_end_with_jump (sub1_fcall, NULL, 1052 gcc_jit_block_end_with_jump (sub1_fcall_block, NULL,
927 bb_map[pc].gcc_bb); 1053 bb_map[pc].gcc_bb);
928 } 1054 }
929 1055
@@ -1053,32 +1179,32 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length,
1053 case Bgotoifnil: 1179 case Bgotoifnil:
1054 op = FETCH2; 1180 op = FETCH2;
1055 POP1; 1181 POP1;
1056 comp_emit_comparison (GCC_JIT_COMPARISON_EQ, args[0], nil, 1182 comp_emit_comp_jump (GCC_JIT_COMPARISON_EQ, args[0], nil,
1057 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1183 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1058 break; 1184 break;
1059 1185
1060 case Bgotoifnonnil: 1186 case Bgotoifnonnil:
1061 op = FETCH2; 1187 op = FETCH2;
1062 POP1; 1188 POP1;
1063 comp_emit_comparison (GCC_JIT_COMPARISON_NE, args[0], nil, 1189 comp_emit_comp_jump (GCC_JIT_COMPARISON_NE, args[0], nil,
1064 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1190 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1065 break; 1191 break;
1066 1192
1067 case Bgotoifnilelsepop: 1193 case Bgotoifnilelsepop:
1068 op = FETCH2; 1194 op = FETCH2;
1069 comp_emit_comparison (GCC_JIT_COMPARISON_EQ, 1195 comp_emit_comp_jump (GCC_JIT_COMPARISON_EQ,
1070 gcc_jit_lvalue_as_rvalue (TOS), 1196 gcc_jit_lvalue_as_rvalue (TOS),
1071 nil, 1197 nil,
1072 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1198 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1073 POP1; 1199 POP1;
1074 break; 1200 break;
1075 1201
1076 case Bgotoifnonnilelsepop: 1202 case Bgotoifnonnilelsepop:
1077 op = FETCH2; 1203 op = FETCH2;
1078 comp_emit_comparison (GCC_JIT_COMPARISON_NE, 1204 comp_emit_comp_jump (GCC_JIT_COMPARISON_NE,
1079 gcc_jit_lvalue_as_rvalue (TOS), 1205 gcc_jit_lvalue_as_rvalue (TOS),
1080 nil, 1206 nil,
1081 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1207 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1082 POP1; 1208 POP1;
1083 break; 1209 break;
1084 1210
@@ -1239,35 +1365,35 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length,
1239 op = FETCH - 128; 1365 op = FETCH - 128;
1240 op += pc; 1366 op += pc;
1241 POP1; 1367 POP1;
1242 comp_emit_comparison (GCC_JIT_COMPARISON_EQ, args[0], nil, 1368 comp_emit_comp_jump (GCC_JIT_COMPARISON_EQ, args[0], nil,
1243 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1369 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1244 break; 1370 break;
1245 1371
1246 case BRgotoifnonnil: 1372 case BRgotoifnonnil:
1247 op = FETCH - 128; 1373 op = FETCH - 128;
1248 op += pc; 1374 op += pc;
1249 POP1; 1375 POP1;
1250 comp_emit_comparison (GCC_JIT_COMPARISON_NE, args[0], nil, 1376 comp_emit_comp_jump (GCC_JIT_COMPARISON_NE, args[0], nil,
1251 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1377 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1252 break; 1378 break;
1253 1379
1254 case BRgotoifnilelsepop: 1380 case BRgotoifnilelsepop:
1255 op = FETCH - 128; 1381 op = FETCH - 128;
1256 op += pc; 1382 op += pc;
1257 comp_emit_comparison (GCC_JIT_COMPARISON_EQ, 1383 comp_emit_comp_jump (GCC_JIT_COMPARISON_EQ,
1258 gcc_jit_lvalue_as_rvalue (TOS), 1384 gcc_jit_lvalue_as_rvalue (TOS),
1259 nil, 1385 nil,
1260 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1386 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1261 POP1; 1387 POP1;
1262 break; 1388 break;
1263 1389
1264 case BRgotoifnonnilelsepop: 1390 case BRgotoifnonnilelsepop:
1265 op = FETCH - 128; 1391 op = FETCH - 128;
1266 op += pc; 1392 op += pc;
1267 comp_emit_comparison (GCC_JIT_COMPARISON_NE, 1393 comp_emit_comp_jump (GCC_JIT_COMPARISON_NE,
1268 gcc_jit_lvalue_as_rvalue (TOS), 1394 gcc_jit_lvalue_as_rvalue (TOS),
1269 nil, 1395 nil,
1270 bb_map[op].gcc_bb, bb_map[pc].gcc_bb); 1396 bb_map[op].gcc_bb, bb_map[pc].gcc_bb);
1271 POP1; 1397 POP1;
1272 break; 1398 break;
1273 1399
@@ -1464,6 +1590,9 @@ init_comp (void)
1464 comp.void_ptr_type = 1590 comp.void_ptr_type =
1465 gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_VOID_PTR); 1591 gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_VOID_PTR);
1466 comp.int_type = gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_INT); 1592 comp.int_type = gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_INT);
1593 comp.unsigned_type = gcc_jit_context_get_type (comp.ctxt,
1594 GCC_JIT_TYPE_UNSIGNED_INT);
1595 comp.bool_type = gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_BOOL);
1467 comp.long_type = gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_LONG); 1596 comp.long_type = gcc_jit_context_get_type (comp.ctxt, GCC_JIT_TYPE_LONG);
1468 comp.long_long_type = gcc_jit_context_get_type (comp.ctxt, 1597 comp.long_long_type = gcc_jit_context_get_type (comp.ctxt,
1469 GCC_JIT_TYPE_LONG_LONG); 1598 GCC_JIT_TYPE_LONG_LONG);
@@ -1498,6 +1627,38 @@ init_comp (void)
1498 "LispObj", 1627 "LispObj",
1499 2, 1628 2,
1500 lisp_obj_fields); 1629 lisp_obj_fields);
1630
1631 comp.cast_union_as_ll =
1632 gcc_jit_context_new_field (comp.ctxt,
1633 NULL,
1634 comp.long_long_type, /* FIXME? */
1635 "ll");
1636 comp.cast_union_as_u =
1637 gcc_jit_context_new_field (comp.ctxt,
1638 NULL,
1639 comp.unsigned_type,
1640 "u");
1641 comp.cast_union_as_i =
1642 gcc_jit_context_new_field (comp.ctxt,
1643 NULL,
1644 comp.int_type,
1645 "i");
1646 comp.cast_union_as_b =
1647 gcc_jit_context_new_field (comp.ctxt,
1648 NULL,
1649 comp.bool_type,
1650 "b");
1651
1652 gcc_jit_field *cast_union_fields[4] =
1653 { comp.cast_union_as_ll,
1654 comp.cast_union_as_u,
1655 comp.cast_union_as_i,
1656 comp.cast_union_as_b,};
1657 comp.cast_union_type = gcc_jit_context_new_union_type (comp.ctxt,
1658 NULL,
1659 "cast_union",
1660 4,
1661 cast_union_fields);
1501 comp.most_positive_fixnum = 1662 comp.most_positive_fixnum =
1502 gcc_jit_context_new_rvalue_from_long (comp.ctxt, 1663 gcc_jit_context_new_rvalue_from_long (comp.ctxt,
1503 comp.long_long_type, /* FIXME? */ 1664 comp.long_long_type, /* FIXME? */