github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-opcode-apply.c (about) 1 /* 2 * jit-opcode-apply.c - Constant folding. 3 * 4 * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 * 6 * This file is part of the libjit library. 7 * 8 * The libjit library is free software: you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation, either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * The libjit library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with the libjit library. If not, see 20 * <http://www.gnu.org/licenses/>. 21 */ 22 23 #include "jit-internal.h" 24 #include "jit-rules.h" 25 26 /* 27 * Signatures for the different intrinsics 28 */ 29 typedef jit_int (*jit_cf_i_i_func)(jit_int value); 30 typedef jit_int (*jit_cf_i_ii_func)(jit_int value1, jit_int value2); 31 typedef jit_int (*jit_cf_i_piii_func)(jit_int *result, jit_int value1, jit_int value2); 32 typedef jit_int (*jit_cf_i_iI_func)(jit_int value1, jit_uint value2); 33 typedef jit_int (*jit_cf_i_II_func)(jit_uint value1, jit_uint value2); 34 typedef jit_uint (*jit_cf_I_I_func)(jit_uint value); 35 typedef jit_uint (*jit_cf_I_II_func)(jit_uint value1, jit_uint value2); 36 typedef jit_int (*jit_cf_i_pIII_func)(jit_uint *result, jit_uint value1, jit_uint value2); 37 typedef jit_long (*jit_cf_l_l_func)(jit_long value); 38 typedef jit_long (*jit_cf_l_ll_func)(jit_long value1, jit_long value2); 39 typedef jit_int (*jit_cf_i_plll_func)(jit_long *result, jit_long value1, jit_long value2); 40 typedef jit_int (*jit_cf_i_l_func)(jit_long value); 41 typedef jit_int (*jit_cf_i_ll_func)(jit_long value1, jit_long value2); 42 typedef jit_long (*jit_cf_l_lI_func)(jit_long value1, jit_uint value2); 43 typedef jit_ulong (*jit_cf_L_L_func)(jit_ulong value); 44 typedef jit_ulong (*jit_cf_L_LL_func)(jit_ulong value1, jit_ulong value2); 45 typedef jit_int (*jit_cf_i_pLLL_func)(jit_ulong *result, jit_ulong value1, jit_ulong value2); 46 typedef jit_int (*jit_cf_i_LL_func)(jit_ulong value1, jit_ulong value2); 47 typedef jit_ulong (*jit_cf_L_LI_func)(jit_ulong value1, jit_uint value2); 48 typedef jit_float32 (*jit_cf_f_f_func)(jit_float32 value); 49 typedef jit_float32 (*jit_cf_f_ff_func)(jit_float32 value1, jit_float32 value2); 50 typedef jit_int (*jit_cf_i_f_func)(jit_float32 value); 51 typedef jit_int (*jit_cf_i_ff_func)(jit_float32 value1, jit_float32 value2); 52 typedef jit_float64 (*jit_cf_d_d_func)(jit_float64 value); 53 typedef jit_float64 (*jit_cf_d_dd_func)(jit_float64 value1, jit_float64 value2); 54 typedef jit_int (*jit_cf_i_d_func)(jit_float64 value); 55 typedef jit_int (*jit_cf_i_dd_func)(jit_float64 value1, jit_float64 value2); 56 typedef jit_nfloat (*jit_cf_D_D_func)(jit_nfloat value); 57 typedef jit_nfloat (*jit_cf_D_DD_func)(jit_nfloat value1, jit_nfloat value2); 58 typedef jit_int (*jit_cf_i_D_func)(jit_nfloat value); 59 typedef jit_int (*jit_cf_i_DD_func)(jit_nfloat value1, jit_nfloat value2); 60 61 /* 62 * NOTE: The result type is already set in the result struct. 63 */ 64 static int 65 apply_conv(jit_constant_t *result, jit_value_t value, int overflow_check) 66 { 67 jit_constant_t constant; 68 constant.type = jit_type_promote_int(jit_type_normalize(value->type)); 69 if(!constant.type) 70 { 71 return 0; 72 } 73 switch(constant.type->kind) 74 { 75 case JIT_TYPE_INT: 76 constant.un.int_value = value->address; 77 break; 78 79 case JIT_TYPE_UINT: 80 constant.un.uint_value = value->address; 81 break; 82 83 case JIT_TYPE_LONG: 84 #ifdef JIT_NATIVE_INT64 85 constant.un.long_value = value->address; 86 #else 87 constant.un.long_value = *((jit_long *) value->address); 88 #endif 89 break; 90 91 case JIT_TYPE_ULONG: 92 #ifdef JIT_NATIVE_INT64 93 constant.un.ulong_value = value->address; 94 #else 95 constant.un.ulong_value = *((jit_ulong *) value->address); 96 #endif 97 break; 98 99 case JIT_TYPE_FLOAT32: 100 constant.un.float32_value = *((jit_float32 *) value->address); 101 break; 102 103 case JIT_TYPE_FLOAT64: 104 constant.un.float64_value = *((jit_float64 *) value->address); 105 break; 106 107 case JIT_TYPE_NFLOAT: 108 constant.un.nfloat_value = *((jit_nfloat *) value->address); 109 break; 110 111 default: 112 return 0; 113 } 114 115 return jit_constant_convert(result, &constant, result->type, 116 overflow_check); 117 } 118 119 static int 120 apply_i_i(jit_constant_t *result, jit_value_t value, 121 jit_cf_i_i_func intrinsic) 122 { 123 result->un.int_value = intrinsic(value->address); 124 return 1; 125 } 126 127 static int 128 apply_i_ii(jit_constant_t *result, 129 jit_value_t value1, jit_value_t value2, 130 jit_cf_i_ii_func intrinsic) 131 { 132 result->un.int_value = intrinsic(value1->address, value2->address); 133 return 1; 134 } 135 136 static int 137 apply_i_piii(jit_constant_t *result, 138 jit_value_t value1, jit_value_t value2, 139 jit_cf_i_piii_func intrinsic) 140 { 141 return intrinsic(&result->un.int_value, 142 value1->address, value2->address); 143 } 144 145 static int 146 apply_i_iI(jit_constant_t *result, 147 jit_value_t value1, jit_value_t value2, 148 jit_cf_i_iI_func intrinsic) 149 { 150 result->un.int_value = intrinsic(value1->address, value2->address); 151 return 1; 152 } 153 154 static int 155 apply_i_II(jit_constant_t *result, 156 jit_value_t value1, jit_value_t value2, 157 jit_cf_i_II_func intrinsic) 158 { 159 result->un.int_value = intrinsic(value1->address, value2->address); 160 return 1; 161 } 162 163 static int 164 apply_I_I(jit_constant_t *result, jit_value_t value, 165 jit_cf_I_I_func intrinsic) 166 { 167 result->un.uint_value = intrinsic(value->address); 168 return 1; 169 } 170 171 static int 172 apply_I_II(jit_constant_t *result, 173 jit_value_t value1, jit_value_t value2, 174 jit_cf_I_II_func intrinsic) 175 { 176 result->un.uint_value = intrinsic(value1->address, value2->address); 177 return 1; 178 } 179 180 static int 181 apply_i_pIII(jit_constant_t *result, 182 jit_value_t value1, jit_value_t value2, 183 jit_cf_i_pIII_func intrinsic) 184 { 185 return intrinsic(&result->un.uint_value, 186 value1->address, value2->address); 187 } 188 189 static int 190 apply_l_l(jit_constant_t *result, jit_value_t value1, 191 jit_cf_l_l_func intrinsic) 192 { 193 #ifdef JIT_NATIVE_INT64 194 result->un.long_value = intrinsic(value1->address); 195 #else 196 result->un.long_value = intrinsic(*((jit_long *) value1->address)); 197 #endif 198 return 1; 199 } 200 201 static int 202 apply_l_ll(jit_constant_t *result, 203 jit_value_t value1, jit_value_t value2, 204 jit_cf_l_ll_func intrinsic) 205 { 206 #ifdef JIT_NATIVE_INT64 207 result->un.long_value = intrinsic(value1->address, value2->address); 208 #else 209 result->un.long_value = intrinsic(*((jit_long *) value1->address), 210 *((jit_long *) value2->address)); 211 #endif 212 return 1; 213 } 214 215 static int 216 apply_i_plll(jit_constant_t *result, 217 jit_value_t value1, jit_value_t value2, 218 jit_cf_i_plll_func intrinsic) 219 { 220 #ifdef JIT_NATIVE_INT64 221 return intrinsic(&result->un.long_value, 222 value1->address, value2->address); 223 #else 224 return intrinsic(&result->un.long_value, 225 *((jit_long *) value1->address), 226 *((jit_long *) value2->address)); 227 #endif 228 } 229 230 static int 231 apply_i_l(jit_constant_t *result, 232 jit_value_t value, jit_cf_i_l_func intrinsic) 233 { 234 #ifdef JIT_NATIVE_INT64 235 result->un.int_value = intrinsic(value->address); 236 #else 237 result->un.int_value = intrinsic(*((jit_long *) value->address)); 238 #endif 239 return 1; 240 } 241 242 static int 243 apply_i_ll(jit_constant_t *result, 244 jit_value_t value1, jit_value_t value2, 245 jit_cf_i_ll_func intrinsic) 246 { 247 #ifdef JIT_NATIVE_INT64 248 result->un.int_value = intrinsic(value1->address, value2->address); 249 #else 250 result->un.int_value = intrinsic(*((jit_long *) value1->address), 251 *((jit_long *) value2->address)); 252 #endif 253 return 1; 254 } 255 256 static int 257 apply_l_lI(jit_constant_t *result, 258 jit_value_t value1, jit_value_t value2, 259 jit_cf_l_lI_func intrinsic) 260 { 261 #ifdef JIT_NATIVE_INT64 262 result->un.long_value = intrinsic(value1->address, value2->address); 263 #else 264 result->un.long_value = intrinsic(*((jit_long *) value1->address), 265 value2->address); 266 #endif 267 return 1; 268 } 269 270 static int 271 apply_L_L(jit_constant_t *result, jit_value_t value, 272 jit_cf_L_L_func intrinsic) 273 { 274 #ifdef JIT_NATIVE_INT64 275 result->un.ulong_value = intrinsic(value->address); 276 #else 277 result->un.ulong_value = intrinsic(*((jit_ulong *) value->address)); 278 #endif 279 return 1; 280 } 281 282 static int 283 apply_L_LL(jit_constant_t *result, 284 jit_value_t value1, jit_value_t value2, 285 jit_cf_L_LL_func intrinsic) 286 { 287 #ifdef JIT_NATIVE_INT64 288 result->un.ulong_value = intrinsic(value1->address, value2->address); 289 #else 290 result->un.ulong_value = intrinsic(*((jit_ulong *) value1->address), 291 *((jit_ulong *) value2->address)); 292 #endif 293 return 1; 294 } 295 296 static int 297 apply_i_pLLL(jit_constant_t *result, 298 jit_value_t value1, jit_value_t value2, 299 jit_cf_i_pLLL_func intrinsic) 300 { 301 #ifdef JIT_NATIVE_INT64 302 return intrinsic(&result->un.ulong_value, 303 value1->address, value2->address); 304 #else 305 return intrinsic(&result->un.ulong_value, 306 *((jit_ulong *) value1->address), 307 *((jit_ulong *) value2->address)); 308 #endif 309 } 310 311 static int 312 apply_i_LL(jit_constant_t *result, 313 jit_value_t value1, jit_value_t value2, 314 jit_cf_i_LL_func intrinsic) 315 { 316 #ifdef JIT_NATIVE_INT64 317 result->un.int_value = intrinsic(value1->address, value2->address); 318 #else 319 result->un.int_value = intrinsic(*((jit_ulong *) value1->address), 320 *((jit_ulong *) value2->address)); 321 #endif 322 return 1; 323 } 324 325 static int 326 apply_L_LI(jit_constant_t *result, 327 jit_value_t value1, jit_value_t value2, 328 jit_cf_L_LI_func intrinsic) 329 { 330 #ifdef JIT_NATIVE_INT64 331 result->un.ulong_value = intrinsic(value1->address, value2->address); 332 #else 333 result->un.ulong_value = intrinsic(*((jit_ulong *) value1->address), 334 value2->address); 335 #endif 336 return 1; 337 } 338 339 static int 340 apply_f_f(jit_constant_t *result, jit_value_t value, 341 jit_cf_f_f_func intrinsic) 342 { 343 result->un.float32_value = intrinsic(*((jit_float32 *) value->address)); 344 return 1; 345 } 346 347 static int 348 apply_f_ff(jit_constant_t *result, 349 jit_value_t value1, jit_value_t value2, 350 jit_cf_f_ff_func intrinsic) 351 { 352 result->un.float32_value = intrinsic(*((jit_float32 *) value1->address), 353 *((jit_float32 *) value2->address)); 354 return 1; 355 } 356 357 static int 358 apply_i_f(jit_constant_t *result, jit_value_t value, 359 jit_cf_i_f_func intrinsic) 360 { 361 result->un.int_value = intrinsic(*((jit_float32 *) value->address)); 362 return 1; 363 } 364 365 static int 366 apply_i_ff(jit_constant_t *result, 367 jit_value_t value1, jit_value_t value2, 368 jit_cf_i_ff_func intrinsic) 369 { 370 result->un.int_value = intrinsic(*((jit_float32 *) value1->address), 371 *((jit_float32 *) value2->address)); 372 return 1; 373 } 374 375 static int 376 apply_d_d(jit_constant_t *result, jit_value_t value, 377 jit_cf_d_d_func intrinsic) 378 { 379 result->un.float64_value = intrinsic(*((jit_float64 *) value->address)); 380 return 1; 381 } 382 383 static int 384 apply_d_dd(jit_constant_t *result, 385 jit_value_t value1, jit_value_t value2, 386 jit_cf_d_dd_func intrinsic) 387 { 388 result->un.float64_value = intrinsic(*((jit_float64 *) value1->address), 389 *((jit_float64 *) value2->address)); 390 return 1; 391 } 392 393 static int 394 apply_i_d(jit_constant_t *result, jit_value_t value, 395 jit_cf_i_d_func intrinsic) 396 { 397 result->un.int_value = intrinsic(*((jit_float64 *) value->address)); 398 return 1; 399 } 400 401 static int 402 apply_i_dd(jit_constant_t *result, 403 jit_value_t value1, jit_value_t value2, 404 jit_cf_i_dd_func intrinsic) 405 { 406 result->un.int_value = intrinsic(*((jit_float64 *) value1->address), 407 *((jit_float64 *) value2->address)); 408 return 1; 409 } 410 411 static int 412 apply_D_D(jit_constant_t *result, jit_value_t value, 413 jit_cf_D_D_func intrinsic) 414 { 415 result->un.nfloat_value = intrinsic(*((jit_nfloat *) value->address)); 416 return 1; 417 } 418 419 static int 420 apply_D_DD(jit_constant_t *result, 421 jit_value_t value1, jit_value_t value2, 422 jit_cf_D_DD_func intrinsic) 423 { 424 result->un.nfloat_value = intrinsic(*((jit_nfloat *) value1->address), 425 *((jit_nfloat *) value2->address)); 426 return 1; 427 } 428 429 static int 430 apply_i_D(jit_constant_t *result, 431 jit_value_t value, jit_cf_i_D_func intrinsic) 432 { 433 result->un.int_value = intrinsic(*((jit_nfloat *) value->address)); 434 return 1; 435 } 436 437 static int 438 apply_i_DD(jit_constant_t *const_result, 439 jit_value_t value1, jit_value_t value2, 440 jit_cf_i_DD_func intrinsic) 441 { 442 const_result->un.int_value = intrinsic(*((jit_nfloat *) value1->address), 443 *((jit_nfloat *) value2->address)); 444 return 1; 445 } 446 447 static jit_value_t 448 apply_opcode(jit_function_t func, const _jit_intrinsic_info_t *opcode_info, 449 jit_type_t type, jit_value_t value1, jit_value_t value2) 450 { 451 int success = 0; 452 453 jit_constant_t result; 454 result.type = type; 455 switch(opcode_info->signature) 456 { 457 case JIT_SIG_i_i: 458 success = apply_i_i(&result, value1, 459 (jit_cf_i_i_func) opcode_info->intrinsic); 460 break; 461 462 case JIT_SIG_i_ii: 463 success = apply_i_ii(&result, value1, value2, 464 (jit_cf_i_ii_func) opcode_info->intrinsic); 465 break; 466 467 case JIT_SIG_i_piii: 468 success = apply_i_piii(&result, value1, value2, 469 (jit_cf_i_piii_func) opcode_info->intrinsic); 470 break; 471 472 case JIT_SIG_i_iI: 473 success = apply_i_iI(&result, value1, value2, 474 (jit_cf_i_iI_func) opcode_info->intrinsic); 475 break; 476 477 case JIT_SIG_i_II: 478 success = apply_i_II(&result, value1, value2, 479 (jit_cf_i_II_func) opcode_info->intrinsic); 480 break; 481 482 case JIT_SIG_I_I: 483 success = apply_I_I(&result, value1, 484 (jit_cf_I_I_func) opcode_info->intrinsic); 485 break; 486 487 case JIT_SIG_I_II: 488 success = apply_I_II(&result, value1, value2, 489 (jit_cf_I_II_func) opcode_info->intrinsic); 490 break; 491 492 case JIT_SIG_i_pIII: 493 success = apply_i_pIII(&result, value1, value2, 494 (jit_cf_i_pIII_func) opcode_info->intrinsic); 495 break; 496 497 case JIT_SIG_l_l: 498 success = apply_l_l(&result, value1, 499 (jit_cf_l_l_func) opcode_info->intrinsic); 500 break; 501 502 case JIT_SIG_l_ll: 503 success = apply_l_ll(&result, value1, value2, 504 (jit_cf_l_ll_func) opcode_info->intrinsic); 505 break; 506 507 case JIT_SIG_i_plll: 508 success = apply_i_plll(&result, value1, value2, 509 (jit_cf_i_plll_func) opcode_info->intrinsic); 510 break; 511 512 case JIT_SIG_i_l: 513 success = apply_i_l(&result, value1, 514 (jit_cf_i_l_func) opcode_info->intrinsic); 515 break; 516 517 case JIT_SIG_i_ll: 518 success = apply_i_ll(&result, value1, value2, 519 (jit_cf_i_ll_func) opcode_info->intrinsic); 520 break; 521 522 case JIT_SIG_l_lI: 523 success = apply_l_lI(&result, value1, value2, 524 (jit_cf_l_lI_func) opcode_info->intrinsic); 525 break; 526 527 case JIT_SIG_L_L: 528 success = apply_L_L(&result, value1, 529 (jit_cf_L_L_func) opcode_info->intrinsic); 530 break; 531 532 case JIT_SIG_L_LL: 533 success = apply_L_LL(&result, value1, value2, 534 (jit_cf_L_LL_func) opcode_info->intrinsic); 535 break; 536 537 case JIT_SIG_i_pLLL: 538 success = apply_i_pLLL(&result, value1, value2, 539 (jit_cf_i_pLLL_func) opcode_info->intrinsic); 540 break; 541 542 case JIT_SIG_i_LL: 543 success = apply_i_LL(&result, value1, value2, 544 (jit_cf_i_LL_func) opcode_info->intrinsic); 545 break; 546 547 case JIT_SIG_L_LI: 548 success = apply_L_LI(&result, value1, value2, 549 (jit_cf_L_LI_func) opcode_info->intrinsic); 550 break; 551 552 case JIT_SIG_f_f: 553 success = apply_f_f(&result, value1, 554 (jit_cf_f_f_func) opcode_info->intrinsic); 555 break; 556 557 case JIT_SIG_f_ff: 558 success = apply_f_ff(&result, value1, value2, 559 (jit_cf_f_ff_func) opcode_info->intrinsic); 560 break; 561 562 case JIT_SIG_i_f: 563 success = apply_i_f(&result, value1, 564 (jit_cf_i_f_func) opcode_info->intrinsic); 565 break; 566 567 case JIT_SIG_i_ff: 568 success = apply_i_ff(&result, value1, value2, 569 (jit_cf_i_ff_func) opcode_info->intrinsic); 570 break; 571 572 case JIT_SIG_d_d: 573 success = apply_d_d(&result, value1, 574 (jit_cf_d_d_func) opcode_info->intrinsic); 575 break; 576 577 case JIT_SIG_d_dd: 578 success = apply_d_dd(&result, value1, value2, 579 (jit_cf_d_dd_func) opcode_info->intrinsic); 580 break; 581 582 case JIT_SIG_i_d: 583 success = apply_i_d(&result, value1, 584 (jit_cf_i_d_func) opcode_info->intrinsic); 585 break; 586 587 case JIT_SIG_i_dd: 588 success = apply_i_dd(&result, value1, value2, 589 (jit_cf_i_dd_func) opcode_info->intrinsic); 590 break; 591 592 case JIT_SIG_D_D: 593 success = apply_D_D(&result, value1, 594 (jit_cf_D_D_func) opcode_info->intrinsic); 595 break; 596 597 case JIT_SIG_D_DD: 598 success = apply_D_DD(&result, value1, value2, 599 (jit_cf_D_DD_func) opcode_info->intrinsic); 600 break; 601 602 case JIT_SIG_i_D: 603 success = apply_i_D(&result, value1, 604 (jit_cf_i_D_func) opcode_info->intrinsic); 605 break; 606 607 case JIT_SIG_i_DD: 608 success = apply_i_DD(&result, value1, value2, 609 (jit_cf_i_DD_func) opcode_info->intrinsic); 610 break; 611 612 case JIT_SIG_conv: 613 success = apply_conv(&result, value1, 0); 614 break; 615 616 case JIT_SIG_conv_ovf: 617 success = apply_conv(&result, value1, 1); 618 break; 619 } 620 621 if(!success) 622 { 623 return 0; 624 } 625 626 return jit_value_create_constant(func, &result); 627 } 628 629 static jit_value_t 630 _jit_opcode_apply_helper(jit_function_t func, jit_uint opcode, jit_type_t type, 631 jit_value_t value1, jit_value_t value2) 632 { 633 const _jit_intrinsic_info_t *opcode_info = &_jit_intrinsics[opcode]; 634 635 jit_short flag = opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK; 636 if (flag != _JIT_INTRINSIC_FLAG_NONE) 637 { 638 if (flag != _JIT_INTRINSIC_FLAG_NOT) 639 { 640 return 0; 641 } 642 643 opcode = opcode_info->flags & ~_JIT_INTRINSIC_FLAG_MASK; 644 if(opcode >= JIT_OP_NUM_OPCODES) 645 { 646 return 0; 647 } 648 649 opcode_info = &_jit_intrinsics[opcode]; 650 jit_value_t value = apply_opcode(func, opcode_info, type, 651 value1, value2); 652 if(value) 653 { 654 /* 655 * We have to apply a logical not to the constant 656 * jit_int result value. 657 */ 658 value->address = !value->address; 659 } 660 return value; 661 } 662 663 return apply_opcode(func, opcode_info, type, value1, value2); 664 } 665 666 jit_value_t 667 _jit_opcode_apply_unary(jit_function_t func, jit_uint opcode, jit_value_t value, 668 jit_type_t type) 669 { 670 if(opcode >= JIT_OP_NUM_OPCODES) 671 { 672 return 0; 673 } 674 if(!value->is_constant) 675 { 676 return 0; 677 } 678 return _jit_opcode_apply_helper(func, opcode, type, value, value); 679 } 680 681 jit_value_t 682 _jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_value_t value1, 683 jit_value_t value2, jit_type_t type) 684 { 685 if(opcode >= JIT_OP_NUM_OPCODES) 686 { 687 return 0; 688 } 689 if(!value1->is_constant || !value2->is_constant) 690 { 691 return 0; 692 } 693 return _jit_opcode_apply_helper(func, opcode, type, value1, value2); 694 }