github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-insn.c (about) 1 /* 2 * jit-insn.c - Functions for manipulating instructions. 3 * 4 * Copyright (C) 2004 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 #include "jit-setjmp.h" 26 #if HAVE_STDLIB_H 27 # include <stdlib.h> 28 #endif 29 #if HAVE_ALLOCA_H 30 # include <alloca.h> 31 #endif 32 #ifdef JIT_WIN32_PLATFORM 33 # include <malloc.h> 34 # ifndef alloca 35 # define alloca _alloca 36 # endif 37 #endif 38 39 /*@ 40 41 @cindex jit-insn.h 42 43 @*/ 44 45 /* 46 * Opcode description blocks. These describe the alternative opcodes 47 * and intrinsic functions to use for various kinds of arguments. 48 */ 49 typedef struct 50 { 51 unsigned short ioper; /* Primary operator for "int" */ 52 unsigned short iuoper; /* Primary operator for "uint" */ 53 unsigned short loper; /* Primary operator for "long" */ 54 unsigned short luoper; /* Primary operator for "ulong" */ 55 unsigned short foper; /* Primary operator for "float32" */ 56 unsigned short doper; /* Primary operator for "float64" */ 57 unsigned short nfoper; /* Primary operator for "nfloat" */ 58 59 void *ifunc; /* Function for "int" */ 60 const char *iname; /* Intrinsic name for "int" */ 61 const jit_intrinsic_descr_t *idesc; /* Descriptor for "int" */ 62 63 void *iufunc; /* Function for "uint" */ 64 const char *iuname; /* Intrinsic name for "uint" */ 65 const jit_intrinsic_descr_t *iudesc; /* Descriptor for "uint" */ 66 67 void *lfunc; /* Function for "long" */ 68 const char *lname; /* Intrinsic name for "long" */ 69 const jit_intrinsic_descr_t *ldesc; /* Descriptor for "long" */ 70 71 void *lufunc; /* Function for "ulong" */ 72 const char *luname; /* Intrinsic name for "ulong" */ 73 const jit_intrinsic_descr_t *ludesc; /* Descriptor for "ulong" */ 74 75 void *ffunc; /* Function for "float32" */ 76 const char *fname; /* Intrinsic name for "float32" */ 77 const jit_intrinsic_descr_t *fdesc; /* Descriptor for "float32" */ 78 79 void *dfunc; /* Function for "float64" */ 80 const char *dname; /* Intrinsic name for "float64" */ 81 const jit_intrinsic_descr_t *ddesc; /* Descriptor for "float64" */ 82 83 void *nffunc; /* Function for "nfloat" */ 84 const char *nfname; /* Intrinsic name for "nfloat" */ 85 const jit_intrinsic_descr_t *nfdesc; /* Descriptor for "nfloat" */ 86 87 } jit_opcode_descr; 88 89 #define jit_intrinsic(name, descr) (void *)name, #name, &descr 90 #define jit_no_intrinsic 0, 0, 0 91 92 /* 93 * Some common intrinsic descriptors that are used in this file. 94 */ 95 static jit_intrinsic_descr_t const descr_i_ii = { 96 (jit_type_t) &_jit_type_int_def, 97 0, 98 (jit_type_t) &_jit_type_int_def, 99 (jit_type_t) &_jit_type_int_def 100 }; 101 static jit_intrinsic_descr_t const descr_e_pi_ii = { 102 (jit_type_t) &_jit_type_int_def, 103 (jit_type_t) &_jit_type_int_def, 104 (jit_type_t) &_jit_type_int_def, 105 (jit_type_t) &_jit_type_int_def 106 }; 107 static jit_intrinsic_descr_t const descr_i_iI = { 108 (jit_type_t) &_jit_type_int_def, 109 0, 110 (jit_type_t) &_jit_type_int_def, 111 (jit_type_t) &_jit_type_uint_def 112 }; 113 static jit_intrinsic_descr_t const descr_i_i = { 114 (jit_type_t) &_jit_type_int_def, 115 0, 116 (jit_type_t) &_jit_type_int_def, 117 0 118 }; 119 static jit_intrinsic_descr_t const descr_I_II = { 120 (jit_type_t) &_jit_type_uint_def, 121 0, 122 (jit_type_t) &_jit_type_uint_def, 123 (jit_type_t) &_jit_type_uint_def 124 }; 125 static jit_intrinsic_descr_t const descr_e_pI_II = { 126 (jit_type_t) &_jit_type_int_def, 127 (jit_type_t) &_jit_type_uint_def, 128 (jit_type_t) &_jit_type_uint_def, 129 (jit_type_t) &_jit_type_uint_def 130 }; 131 static jit_intrinsic_descr_t const descr_I_I = { 132 (jit_type_t) &_jit_type_uint_def, 133 0, 134 (jit_type_t) &_jit_type_uint_def, 135 0 136 }; 137 static jit_intrinsic_descr_t const descr_i_II = { 138 (jit_type_t) &_jit_type_int_def, 139 0, 140 (jit_type_t) &_jit_type_uint_def, 141 (jit_type_t) &_jit_type_uint_def 142 }; 143 static jit_intrinsic_descr_t const descr_l_ll = { 144 (jit_type_t) &_jit_type_long_def, 145 0, 146 (jit_type_t) &_jit_type_long_def, 147 (jit_type_t) &_jit_type_long_def 148 }; 149 static jit_intrinsic_descr_t const descr_e_pl_ll = { 150 (jit_type_t) &_jit_type_int_def, 151 (jit_type_t) &_jit_type_long_def, 152 (jit_type_t) &_jit_type_long_def, 153 (jit_type_t) &_jit_type_long_def 154 }; 155 static jit_intrinsic_descr_t const descr_l_lI = { 156 (jit_type_t) &_jit_type_long_def, 157 0, 158 (jit_type_t) &_jit_type_long_def, 159 (jit_type_t) &_jit_type_uint_def 160 }; 161 static jit_intrinsic_descr_t const descr_l_l = { 162 (jit_type_t) &_jit_type_long_def, 163 0, 164 (jit_type_t) &_jit_type_long_def, 165 0 166 }; 167 static jit_intrinsic_descr_t const descr_i_ll = { 168 (jit_type_t) &_jit_type_int_def, 169 0, 170 (jit_type_t) &_jit_type_long_def, 171 (jit_type_t) &_jit_type_long_def 172 }; 173 static jit_intrinsic_descr_t const descr_i_l = { 174 (jit_type_t) &_jit_type_int_def, 175 0, 176 (jit_type_t) &_jit_type_long_def, 177 0 178 }; 179 static jit_intrinsic_descr_t const descr_L_LL = { 180 (jit_type_t) &_jit_type_ulong_def, 181 0, 182 (jit_type_t) &_jit_type_ulong_def, 183 (jit_type_t) &_jit_type_ulong_def 184 }; 185 static jit_intrinsic_descr_t const descr_e_pL_LL = { 186 (jit_type_t) &_jit_type_int_def, 187 (jit_type_t) &_jit_type_ulong_def, 188 (jit_type_t) &_jit_type_ulong_def, 189 (jit_type_t) &_jit_type_ulong_def 190 }; 191 static jit_intrinsic_descr_t const descr_L_LI = { 192 (jit_type_t) &_jit_type_ulong_def, 193 0, 194 (jit_type_t) &_jit_type_ulong_def, 195 (jit_type_t) &_jit_type_uint_def 196 }; 197 static jit_intrinsic_descr_t const descr_L_L = { 198 (jit_type_t) &_jit_type_ulong_def, 199 0, 200 (jit_type_t) &_jit_type_ulong_def, 201 0 202 }; 203 static jit_intrinsic_descr_t const descr_i_LL = { 204 (jit_type_t) &_jit_type_int_def, 205 0, 206 (jit_type_t) &_jit_type_ulong_def, 207 (jit_type_t) &_jit_type_ulong_def 208 }; 209 static jit_intrinsic_descr_t const descr_f_ff = { 210 (jit_type_t) &_jit_type_float32_def, 211 0, 212 (jit_type_t) &_jit_type_float32_def, 213 (jit_type_t) &_jit_type_float32_def 214 }; 215 static jit_intrinsic_descr_t const descr_f_f = { 216 (jit_type_t) &_jit_type_float32_def, 217 0, 218 (jit_type_t) &_jit_type_float32_def, 219 0 220 }; 221 static jit_intrinsic_descr_t const descr_i_ff = { 222 (jit_type_t) &_jit_type_int_def, 223 0, 224 (jit_type_t) &_jit_type_float32_def, 225 (jit_type_t) &_jit_type_float32_def 226 }; 227 static jit_intrinsic_descr_t const descr_i_f = { 228 (jit_type_t) &_jit_type_int_def, 229 0, 230 (jit_type_t) &_jit_type_float32_def, 231 0 232 }; 233 static jit_intrinsic_descr_t const descr_d_dd = { 234 (jit_type_t) &_jit_type_float64_def, 235 0, 236 (jit_type_t) &_jit_type_float64_def, 237 (jit_type_t) &_jit_type_float64_def 238 }; 239 static jit_intrinsic_descr_t const descr_d_d = { 240 (jit_type_t) &_jit_type_float64_def, 241 0, 242 (jit_type_t) &_jit_type_float64_def, 243 0 244 }; 245 static jit_intrinsic_descr_t const descr_i_dd = { 246 (jit_type_t) &_jit_type_int_def, 247 0, 248 (jit_type_t) &_jit_type_float64_def, 249 (jit_type_t) &_jit_type_float64_def 250 }; 251 static jit_intrinsic_descr_t const descr_i_d = { 252 (jit_type_t) &_jit_type_int_def, 253 0, 254 (jit_type_t) &_jit_type_float64_def, 255 0 256 }; 257 static jit_intrinsic_descr_t const descr_D_DD = { 258 (jit_type_t) &_jit_type_nfloat_def, 259 0, 260 (jit_type_t) &_jit_type_nfloat_def, 261 (jit_type_t) &_jit_type_nfloat_def 262 }; 263 static jit_intrinsic_descr_t const descr_D_D = { 264 (jit_type_t) &_jit_type_nfloat_def, 265 0, 266 (jit_type_t) &_jit_type_nfloat_def, 267 0 268 }; 269 static jit_intrinsic_descr_t const descr_i_DD = { 270 (jit_type_t) &_jit_type_int_def, 271 0, 272 (jit_type_t) &_jit_type_nfloat_def, 273 (jit_type_t) &_jit_type_nfloat_def 274 }; 275 static jit_intrinsic_descr_t const descr_i_D = { 276 (jit_type_t) &_jit_type_int_def, 277 0, 278 (jit_type_t) &_jit_type_nfloat_def, 279 0 280 }; 281 282 /* 283 * Apply a unary operator. 284 */ 285 static jit_value_t 286 apply_unary(jit_function_t func, int oper, jit_value_t value, jit_type_t type) 287 { 288 /* Ensure that we have a function builder */ 289 if(!_jit_function_ensure_builder(func)) 290 { 291 return 0; 292 } 293 294 jit_value_t dest = jit_value_create(func, type); 295 if(!dest) 296 { 297 return 0; 298 } 299 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 300 if(!insn) 301 { 302 return 0; 303 } 304 insn->opcode = (short) oper; 305 insn->dest = dest; 306 insn->value1 = value; 307 jit_value_ref(func, value); 308 309 return dest; 310 } 311 312 /* 313 * Apply a binary operator. 314 */ 315 static jit_value_t 316 apply_binary(jit_function_t func, int oper, jit_value_t value1, jit_value_t value2, 317 jit_type_t type) 318 { 319 /* Ensure that we have a function builder */ 320 if(!_jit_function_ensure_builder(func)) 321 { 322 return 0; 323 } 324 325 jit_value_t dest = jit_value_create(func, type); 326 if(!dest) 327 { 328 return 0; 329 } 330 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 331 if(!insn) 332 { 333 return 0; 334 } 335 insn->opcode = (short) oper; 336 insn->dest = dest; 337 insn->value1 = value1; 338 jit_value_ref(func, value1); 339 insn->value2 = value2; 340 jit_value_ref(func, value2); 341 342 return dest; 343 } 344 345 /* 346 * Apply a ternary operator. 347 */ 348 static int 349 apply_ternary(jit_function_t func, int oper, jit_value_t value1, jit_value_t value2, 350 jit_value_t value3) 351 { 352 /* Ensure that we have a function builder */ 353 if(!_jit_function_ensure_builder(func)) 354 { 355 return 0; 356 } 357 358 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 359 if(!insn) 360 { 361 return 0; 362 } 363 insn->opcode = (short) oper; 364 insn->flags = JIT_INSN_DEST_IS_VALUE; 365 insn->dest = value1; 366 jit_value_ref(func, value1); 367 insn->value1 = value2; 368 jit_value_ref(func, value2); 369 insn->value2 = value3; 370 jit_value_ref(func, value3); 371 372 return 1; 373 } 374 375 /* 376 * Create a note instruction, which doesn't have a result. 377 */ 378 static int 379 create_note(jit_function_t func, int oper, jit_value_t value1, jit_value_t value2) 380 { 381 /* Ensure that we have a function builder */ 382 if(!_jit_function_ensure_builder(func)) 383 { 384 return 0; 385 } 386 387 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 388 if(!insn) 389 { 390 return 0; 391 } 392 insn->opcode = (short) oper; 393 insn->value1 = value1; 394 jit_value_ref(func, value1); 395 insn->value2 = value2; 396 jit_value_ref(func, value2); 397 398 return 1; 399 } 400 401 /* 402 * Create a unary note instruction, which doesn't have a result. 403 */ 404 static int 405 create_unary_note(jit_function_t func, int oper, jit_value_t value) 406 { 407 /* Ensure that we have a function builder */ 408 if(!_jit_function_ensure_builder(func)) 409 { 410 return 0; 411 } 412 413 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 414 if(!insn) 415 { 416 return 0; 417 } 418 insn->opcode = (short) oper; 419 insn->value1 = value; 420 jit_value_ref(func, value); 421 422 return 1; 423 } 424 425 /* 426 * Create a note instruction with no arguments, which doesn't have a result. 427 */ 428 static int 429 create_noarg_note(jit_function_t func, int oper) 430 { 431 /* Ensure that we have a function builder */ 432 if(!_jit_function_ensure_builder(func)) 433 { 434 return 0; 435 } 436 437 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 438 if(!insn) 439 { 440 return 0; 441 } 442 insn->opcode = (short) oper; 443 444 return 1; 445 } 446 447 /* 448 * Create a note instruction with only a destination. 449 */ 450 static jit_value_t 451 create_dest_note(jit_function_t func, int oper, jit_type_t type) 452 { 453 /* Ensure that we have a function builder */ 454 if(!_jit_function_ensure_builder(func)) 455 { 456 return 0; 457 } 458 459 jit_value_t dest = jit_value_create(func, type); 460 if(!dest) 461 { 462 return 0; 463 } 464 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 465 if(!insn) 466 { 467 return 0; 468 } 469 insn->opcode = (short) oper; 470 insn->dest = dest; 471 472 return dest; 473 } 474 475 /* 476 * Get the common type to use for a binary operator. 477 */ 478 static jit_type_t 479 common_binary(jit_type_t type1, jit_type_t type2, int int_only, int float_only) 480 { 481 type1 = jit_type_promote_int(jit_type_normalize(type1)); 482 type2 = jit_type_promote_int(jit_type_normalize(type2)); 483 if(!float_only) 484 { 485 if(type1 == jit_type_int) 486 { 487 if(type2 == jit_type_int || type2 == jit_type_uint) 488 { 489 return jit_type_int; 490 } 491 else if(type2 == jit_type_long || type2 == jit_type_ulong) 492 { 493 return jit_type_long; 494 } 495 } 496 else if(type1 == jit_type_uint) 497 { 498 if(type2 == jit_type_int || type2 == jit_type_uint || 499 type2 == jit_type_long || type2 == jit_type_ulong) 500 { 501 return type2; 502 } 503 } 504 else if(type1 == jit_type_long) 505 { 506 if(type2 == jit_type_int || type2 == jit_type_uint || 507 type2 == jit_type_long || type2 == jit_type_ulong) 508 { 509 return jit_type_long; 510 } 511 } 512 else if(type1 == jit_type_ulong) 513 { 514 if(type2 == jit_type_int || type2 == jit_type_long) 515 { 516 return jit_type_long; 517 } 518 else if(type2 == jit_type_uint || type2 == jit_type_ulong) 519 { 520 return jit_type_ulong; 521 } 522 } 523 if(int_only) 524 { 525 return jit_type_long; 526 } 527 } 528 if(type1 == jit_type_nfloat || type2 == jit_type_nfloat) 529 { 530 return jit_type_nfloat; 531 } 532 else if(type1 == jit_type_float64 || type2 == jit_type_float64) 533 { 534 return jit_type_float64; 535 } 536 else if(type1 == jit_type_float32 || type2 == jit_type_float32) 537 { 538 return jit_type_float32; 539 } 540 else 541 { 542 /* Probably integer arguments when "float_only" is set */ 543 return jit_type_nfloat; 544 } 545 } 546 547 /* 548 * Apply an intrinsic. 549 */ 550 static jit_value_t 551 apply_intrinsic(jit_function_t func, const jit_opcode_descr *descr, 552 jit_value_t value1, jit_value_t value2, jit_type_t type) 553 { 554 switch (type->kind) 555 { 556 default: /* Shouldn't happen */ 557 case JIT_TYPE_INT: 558 return jit_insn_call_intrinsic(func, descr->iname, 559 descr->ifunc, descr->idesc, 560 value1, value2); 561 case JIT_TYPE_UINT: 562 return jit_insn_call_intrinsic(func, descr->iuname, 563 descr->iufunc, descr->iudesc, 564 value1, value2); 565 case JIT_TYPE_LONG: 566 return jit_insn_call_intrinsic(func, descr->lname, 567 descr->lfunc, descr->ldesc, 568 value1, value2); 569 case JIT_TYPE_ULONG: 570 return jit_insn_call_intrinsic(func, descr->luname, 571 descr->lufunc, descr->ludesc, 572 value1, value2); 573 case JIT_TYPE_FLOAT32: 574 return jit_insn_call_intrinsic(func, descr->fname, 575 descr->ffunc, descr->fdesc, 576 value1, value2); 577 case JIT_TYPE_FLOAT64: 578 return jit_insn_call_intrinsic(func, descr->dname, 579 descr->dfunc, descr->ddesc, 580 value1, value2); 581 case JIT_TYPE_NFLOAT: 582 return jit_insn_call_intrinsic(func, descr->nfname, 583 descr->nffunc, descr->nfdesc, 584 value1, value2); 585 } 586 } 587 588 /* 589 * Apply a unary arithmetic operator, after coercing the 590 * argument to a suitable numeric type. 591 */ 592 static jit_value_t 593 apply_unary_arith(jit_function_t func, const jit_opcode_descr *descr, 594 jit_value_t value, int int_only, int float_only, 595 int overflow_check) 596 { 597 jit_type_t type = common_binary(value->type, value->type, int_only, float_only); 598 599 int oper; 600 const jit_intrinsic_descr_t *desc; 601 switch (type->kind) 602 { 603 default: /* Shouldn't happen */ 604 case JIT_TYPE_INT: 605 oper = descr->ioper; 606 desc = descr->idesc; 607 break; 608 case JIT_TYPE_UINT: 609 oper = descr->iuoper; 610 desc = descr->iudesc; 611 break; 612 case JIT_TYPE_LONG: 613 oper = descr->loper; 614 desc = descr->ldesc; 615 break; 616 case JIT_TYPE_ULONG: 617 oper = descr->luoper; 618 desc = descr->ludesc; 619 break; 620 case JIT_TYPE_FLOAT32: 621 oper = descr->foper; 622 desc = descr->fdesc; 623 break; 624 case JIT_TYPE_FLOAT64: 625 oper = descr->doper; 626 desc = descr->ddesc; 627 break; 628 case JIT_TYPE_NFLOAT: 629 oper = descr->nfoper; 630 desc = descr->nfdesc; 631 break; 632 } 633 634 value = jit_insn_convert(func, value, type, overflow_check); 635 if(!value) 636 { 637 return 0; 638 } 639 if(jit_value_is_constant(value)) 640 { 641 jit_value_t result = _jit_opcode_apply_unary(func, oper, value, type); 642 if(result) 643 { 644 return result; 645 } 646 } 647 648 if(desc && desc->ptr_result_type) 649 { 650 func->builder->may_throw = 1; 651 } 652 if(!_jit_opcode_is_supported(oper)) 653 { 654 return apply_intrinsic(func, descr, value, 0, type); 655 } 656 return apply_unary(func, oper, value, type); 657 } 658 659 /* 660 * Apply a binary arithmetic operator, after coercing both 661 * arguments to a common type. 662 */ 663 static jit_value_t 664 apply_arith(jit_function_t func, const jit_opcode_descr *descr, 665 jit_value_t value1, jit_value_t value2, 666 int int_only, int float_only, int overflow_check) 667 { 668 jit_type_t type = common_binary(value1->type, value2->type, int_only, float_only); 669 670 int oper; 671 const jit_intrinsic_descr_t *desc; 672 switch (type->kind) 673 { 674 default: /* Shouldn't happen */ 675 case JIT_TYPE_INT: 676 oper = descr->ioper; 677 desc = descr->idesc; 678 break; 679 case JIT_TYPE_UINT: 680 oper = descr->iuoper; 681 desc = descr->iudesc; 682 break; 683 case JIT_TYPE_LONG: 684 oper = descr->loper; 685 desc = descr->ldesc; 686 break; 687 case JIT_TYPE_ULONG: 688 oper = descr->luoper; 689 desc = descr->ludesc; 690 break; 691 case JIT_TYPE_FLOAT32: 692 oper = descr->foper; 693 desc = descr->fdesc; 694 break; 695 case JIT_TYPE_FLOAT64: 696 oper = descr->doper; 697 desc = descr->ddesc; 698 break; 699 case JIT_TYPE_NFLOAT: 700 oper = descr->nfoper; 701 desc = descr->nfdesc; 702 break; 703 } 704 705 value1 = jit_insn_convert(func, value1, type, overflow_check); 706 value2 = jit_insn_convert(func, value2, type, overflow_check); 707 if(!value1 || !value2) 708 { 709 return 0; 710 } 711 if(jit_value_is_constant(value1) && jit_value_is_constant(value2)) 712 { 713 jit_value_t result = _jit_opcode_apply(func, oper, value1, value2, type); 714 if(result) 715 { 716 return result; 717 } 718 } 719 720 if(desc && desc->ptr_result_type) 721 { 722 func->builder->may_throw = 1; 723 } 724 if(!_jit_opcode_is_supported(oper)) 725 { 726 return apply_intrinsic(func, descr, value1, value2, type); 727 } 728 return apply_binary(func, oper, value1, value2, type); 729 } 730 731 /* 732 * Apply a binary shift operator, after coercing both 733 * arguments to suitable types. 734 */ 735 static jit_value_t 736 apply_shift(jit_function_t func, const jit_opcode_descr *descr, 737 jit_value_t value1, jit_value_t value2) 738 { 739 jit_type_t type = common_binary(value1->type, value1->type, 1, 0); 740 741 int oper; 742 switch (type->kind) 743 { 744 case JIT_TYPE_INT: 745 oper = descr->ioper; 746 break; 747 case JIT_TYPE_UINT: 748 oper = descr->iuoper; 749 break; 750 case JIT_TYPE_LONG: 751 oper = descr->loper; 752 break; 753 default: /* Shouldn't happen */ 754 case JIT_TYPE_ULONG: 755 oper = descr->luoper; 756 break; 757 } 758 759 jit_type_t count_type = jit_type_promote_int(jit_type_normalize(value2->type)); 760 if(count_type != jit_type_int) 761 { 762 count_type = jit_type_uint; 763 } 764 765 value1 = jit_insn_convert(func, value1, type, 0); 766 value2 = jit_insn_convert(func, value2, count_type, 0); 767 if(!value1 || !value2) 768 { 769 return 0; 770 } 771 if(jit_value_is_constant(value1) && jit_value_is_constant(value2)) 772 { 773 jit_value_t result = _jit_opcode_apply(func, oper, value1, value2, type); 774 if(result) 775 { 776 return result; 777 } 778 } 779 780 if(!_jit_opcode_is_supported(oper)) 781 { 782 return apply_intrinsic(func, descr, value1, value2, type); 783 } 784 return apply_binary(func, oper, value1, value2, type); 785 } 786 787 /* 788 * Apply a binary comparison operator, after coercing both 789 * arguments to a common type. 790 */ 791 static jit_value_t 792 apply_compare(jit_function_t func, const jit_opcode_descr *descr, 793 jit_value_t value1, jit_value_t value2, int float_only) 794 { 795 jit_type_t type = common_binary(value1->type, value2->type, 0, float_only); 796 797 int oper; 798 switch (type->kind) 799 { 800 default: /* Shouldn't happen */ 801 case JIT_TYPE_INT: 802 oper = descr->ioper; 803 break; 804 case JIT_TYPE_UINT: 805 oper = descr->iuoper; 806 break; 807 case JIT_TYPE_LONG: 808 oper = descr->loper; 809 break; 810 case JIT_TYPE_ULONG: 811 oper = descr->luoper; 812 break; 813 case JIT_TYPE_FLOAT32: 814 oper = descr->foper; 815 break; 816 case JIT_TYPE_FLOAT64: 817 oper = descr->doper; 818 break; 819 case JIT_TYPE_NFLOAT: 820 oper = descr->nfoper; 821 break; 822 } 823 824 value1 = jit_insn_convert(func, value1, type, 0); 825 value2 = jit_insn_convert(func, value2, type, 0); 826 if(!value1 || !value2) 827 { 828 return 0; 829 } 830 if(jit_value_is_constant(value1) && jit_value_is_constant(value2)) 831 { 832 jit_value_t result = _jit_opcode_apply(func, oper, value1, value2, jit_type_int); 833 if(result) 834 { 835 return result; 836 } 837 } 838 839 if(!_jit_opcode_is_supported(oper)) 840 { 841 return apply_intrinsic(func, descr, value1, value2, type); 842 } 843 return apply_binary(func, oper, value1, value2, jit_type_int); 844 } 845 846 /* 847 * Apply a unary test to a floating point value. 848 */ 849 static jit_value_t 850 test_float_value(jit_function_t func, const jit_opcode_descr *descr, jit_value_t value) 851 { 852 jit_type_t type = jit_type_normalize(value->type); 853 854 int oper; 855 if(type == jit_type_float32) 856 { 857 oper = descr->foper; 858 } 859 else if(type == jit_type_float64) 860 { 861 oper = descr->doper; 862 } 863 else if(type == jit_type_nfloat) 864 { 865 oper = descr->nfoper; 866 } 867 else 868 { 869 /* if the value is not a float then the result is false */ 870 return jit_value_create_nint_constant(func, jit_type_int, 0); 871 } 872 873 if(!_jit_opcode_is_supported(oper)) 874 { 875 return apply_intrinsic(func, descr, value, 0, type); 876 } 877 return apply_unary(func, oper, value, jit_type_int); 878 } 879 880 /*@ 881 * @deftypefun int jit_insn_get_opcode (jit_insn_t @var{insn}) 882 * Get the opcode that is associated with an instruction. 883 * @end deftypefun 884 @*/ 885 int 886 jit_insn_get_opcode(jit_insn_t insn) 887 { 888 return insn->opcode; 889 } 890 891 /*@ 892 * @deftypefun jit_value_t jit_insn_get_dest (jit_insn_t @var{insn}) 893 * Get the destination value that is associated with an instruction. 894 * Returns NULL if the instruction does not have a destination. 895 * @end deftypefun 896 @*/ 897 jit_value_t 898 jit_insn_get_dest(jit_insn_t insn) 899 { 900 if((insn->flags & JIT_INSN_DEST_OTHER_FLAGS) != 0) 901 { 902 return 0; 903 } 904 return insn->dest; 905 } 906 907 /*@ 908 * @deftypefun jit_value_t jit_insn_get_value1 (jit_insn_t @var{insn}) 909 * Get the first argument value that is associated with an instruction. 910 * Returns NULL if the instruction does not have a first argument value. 911 * @end deftypefun 912 @*/ 913 jit_value_t 914 jit_insn_get_value1(jit_insn_t insn) 915 { 916 if((insn->flags & JIT_INSN_VALUE1_OTHER_FLAGS) != 0) 917 { 918 return 0; 919 } 920 return insn->value1; 921 } 922 923 /*@ 924 * @deftypefun jit_value_t jit_insn_get_value2 (jit_insn_t @var{insn}) 925 * Get the second argument value that is associated with an instruction. 926 * Returns NULL if the instruction does not have a second argument value. 927 * @end deftypefun 928 @*/ 929 jit_value_t 930 jit_insn_get_value2(jit_insn_t insn) 931 { 932 if((insn->flags & JIT_INSN_VALUE2_OTHER_FLAGS) != 0) 933 { 934 return 0; 935 } 936 return insn->value2; 937 } 938 939 /*@ 940 * @deftypefun jit_label_t jit_insn_get_label (jit_insn_t @var{insn}) 941 * Get the label for a branch target from an instruction. 942 * Returns NULL if the instruction does not have a branch target. 943 * @end deftypefun 944 @*/ 945 jit_label_t 946 jit_insn_get_label(jit_insn_t insn) 947 { 948 if((insn->flags & JIT_INSN_DEST_IS_LABEL) != 0) 949 { 950 return (jit_label_t) insn->dest; 951 } 952 if((insn->flags & JIT_INSN_VALUE1_IS_LABEL) != 0) 953 { 954 /* "address_of_label" instruction */ 955 return (jit_label_t) insn->value1; 956 } 957 return 0; 958 } 959 960 /*@ 961 * @deftypefun jit_function_t jit_insn_get_function (jit_insn_t @var{insn}) 962 * Get the function for a call instruction. Returns NULL if the 963 * instruction does not refer to a called function. 964 * @end deftypefun 965 @*/ 966 jit_function_t 967 jit_insn_get_function(jit_insn_t insn) 968 { 969 if((insn->flags & JIT_INSN_DEST_IS_FUNCTION) == 0) 970 { 971 return 0; 972 } 973 return (jit_function_t) insn->dest; 974 } 975 976 /*@ 977 * @deftypefun {void *} jit_insn_get_native (jit_insn_t @var{insn}) 978 * Get the function pointer for a native call instruction. 979 * Returns NULL if the instruction does not refer to a native 980 * function call. 981 * @end deftypefun 982 @*/ 983 void * 984 jit_insn_get_native(jit_insn_t insn) 985 { 986 if((insn->flags & JIT_INSN_DEST_IS_NATIVE) == 0) 987 { 988 return 0; 989 } 990 return (void *) insn->dest; 991 } 992 993 /*@ 994 * @deftypefun {const char *} jit_insn_get_name (jit_insn_t @var{insn}) 995 * Get the diagnostic name for a function call. Returns NULL 996 * if the instruction does not have a diagnostic name. 997 * @end deftypefun 998 @*/ 999 const char * 1000 jit_insn_get_name(jit_insn_t insn) 1001 { 1002 if((insn->flags & JIT_INSN_VALUE1_IS_NAME) == 0) 1003 { 1004 return 0; 1005 } 1006 return (const char *) insn->value1; 1007 } 1008 1009 /*@ 1010 * @deftypefun jit_type_t jit_insn_get_signature (jit_insn_t @var{insn}) 1011 * Get the signature for a function call instruction. Returns NULL 1012 * if the instruction is not a function call. 1013 * @end deftypefun 1014 @*/ 1015 jit_type_t 1016 jit_insn_get_signature(jit_insn_t insn) 1017 { 1018 if((insn->flags & JIT_INSN_VALUE2_IS_SIGNATURE) == 0) 1019 { 1020 return 0; 1021 } 1022 return (jit_type_t) insn->value2; 1023 } 1024 1025 /*@ 1026 * @deftypefun int jit_insn_dest_is_value (jit_insn_t @var{insn}) 1027 * Returns a non-zero value if the destination for @var{insn} is 1028 * actually a source value. This can happen with instructions 1029 * such as @code{jit_insn_store_relative} where the instruction 1030 * needs three source operands, and the real destination is a 1031 * side-effect on one of the sources. 1032 * @end deftypefun 1033 @*/ 1034 int 1035 jit_insn_dest_is_value(jit_insn_t insn) 1036 { 1037 return (insn->flags & JIT_INSN_DEST_IS_VALUE) != 0; 1038 } 1039 1040 static int 1041 new_block_with_label(jit_function_t func, jit_label_t *label, int force_new_block) 1042 { 1043 /* Ensure that we have a function builder */ 1044 if(!_jit_function_ensure_builder(func)) 1045 { 1046 return 0; 1047 } 1048 1049 /* Flush any stack pops that were deferred previously */ 1050 if(!jit_insn_flush_defer_pop(func, 0)) 1051 { 1052 return 0; 1053 } 1054 1055 /* Create a new block if required */ 1056 jit_block_t block; 1057 jit_block_t current_block = func->builder->current_block; 1058 if(force_new_block || _jit_block_get_last(current_block)) 1059 { 1060 block = _jit_block_create(func); 1061 if(!block) 1062 { 1063 return 0; 1064 } 1065 } 1066 else 1067 { 1068 /* Reuse the last empty block */ 1069 block = current_block; 1070 if(block->label != jit_label_undefined && *label == jit_label_undefined) 1071 { 1072 /* Reuse its label if any */ 1073 *label = block->label; 1074 return 1; 1075 } 1076 } 1077 1078 /* Create a new label if required */ 1079 if(*label == jit_label_undefined) 1080 { 1081 *label = func->builder->next_label++; 1082 } 1083 1084 /* Register the label use */ 1085 if(!_jit_block_record_label(block, *label)) 1086 { 1087 _jit_block_destroy(block); 1088 return 0; 1089 } 1090 1091 /* If the block is newly created then insert it to the end of 1092 the function's block list */ 1093 if(block != current_block) 1094 { 1095 _jit_block_attach_before(func->builder->exit_block, block, block); 1096 func->builder->current_block = block; 1097 } 1098 1099 return 1; 1100 } 1101 1102 /*@ 1103 * @deftypefun void jit_insn_label (jit_function_t @var{func}, jit_label_t *@var{label}) 1104 * Start a new basic block within the function @var{func} and give it the 1105 * specified @var{label}. Returns zero if out of memory. 1106 * 1107 * If the contents of @var{label} are @code{jit_label_undefined}, then this 1108 * function will allocate a new label for this block. Otherwise it will 1109 * reuse the specified label from a previous branch instruction. 1110 * @end deftypefun 1111 @*/ 1112 int 1113 jit_insn_label(jit_function_t func, jit_label_t *label) 1114 { 1115 return new_block_with_label(func, label, 1); 1116 } 1117 1118 /*@ 1119 * @deftypefun void jit_insn_label_tight (jit_function_t @var{func}, jit_label_t *@var{label}) 1120 * Start a new basic block within the function @var{func} and give it the 1121 * specified @var{label} but attempt to reuse the last block if it is empty. 1122 * Returns zero if out of memory. 1123 * 1124 * If the contents of @var{label} are @code{jit_label_undefined}, then this 1125 * function will allocate a new label for this block. Otherwise it will 1126 * reuse the specified label from a previous branch instruction. 1127 * @end deftypefun 1128 @*/ 1129 int 1130 jit_insn_label_tight(jit_function_t func, jit_label_t *label) 1131 { 1132 return new_block_with_label(func, label, 0); 1133 } 1134 1135 /*@ 1136 * @deftypefun int jit_insn_new_block (jit_function_t @var{func}) 1137 * Start a new basic block, without giving it an explicit label. Returns a 1138 * non-zero value on success. 1139 * @end deftypefun 1140 @*/ 1141 int 1142 jit_insn_new_block(jit_function_t func) 1143 { 1144 /* Create a new block */ 1145 jit_block_t block = _jit_block_create(func); 1146 if(!block) 1147 { 1148 return 0; 1149 } 1150 1151 #ifdef _JIT_BLOCK_DEBUG 1152 jit_label_t label = func->builder->next_label++; 1153 if(!_jit_block_record_label(block, label)) 1154 { 1155 _jit_block_destroy(block); 1156 return 0; 1157 } 1158 #endif 1159 1160 /* Insert the block to the end of the function's block list */ 1161 _jit_block_attach_before(func->builder->exit_block, block, block); 1162 func->builder->current_block = block; 1163 1164 return 1; 1165 } 1166 1167 int 1168 _jit_load_opcode(int base_opcode, jit_type_t type) 1169 { 1170 type = jit_type_normalize(type); 1171 if(!type) 1172 { 1173 return 0; 1174 } 1175 1176 switch(type->kind) 1177 { 1178 case JIT_TYPE_SBYTE: 1179 return base_opcode; 1180 1181 case JIT_TYPE_UBYTE: 1182 return base_opcode + 1; 1183 1184 case JIT_TYPE_SHORT: 1185 return base_opcode + 2; 1186 1187 case JIT_TYPE_USHORT: 1188 return base_opcode + 3; 1189 1190 case JIT_TYPE_INT: 1191 case JIT_TYPE_UINT: 1192 return base_opcode + 4; 1193 1194 case JIT_TYPE_LONG: 1195 case JIT_TYPE_ULONG: 1196 return base_opcode + 5; 1197 1198 case JIT_TYPE_FLOAT32: 1199 return base_opcode + 6; 1200 1201 case JIT_TYPE_FLOAT64: 1202 return base_opcode + 7; 1203 1204 case JIT_TYPE_NFLOAT: 1205 return base_opcode + 8; 1206 1207 case JIT_TYPE_STRUCT: 1208 case JIT_TYPE_UNION: 1209 return base_opcode + 9; 1210 } 1211 1212 return 0; 1213 } 1214 1215 int 1216 _jit_store_opcode(int base_opcode, int small_base, jit_type_t type) 1217 { 1218 /* Copy instructions are in two ranges: adjust for them */ 1219 if(small_base) 1220 { 1221 base_opcode -= 2; 1222 } 1223 else 1224 { 1225 small_base = base_opcode; 1226 } 1227 1228 /* Determine which opcode to use */ 1229 type = jit_type_normalize(type); 1230 switch(type->kind) 1231 { 1232 case JIT_TYPE_SBYTE: 1233 case JIT_TYPE_UBYTE: 1234 return small_base; 1235 1236 case JIT_TYPE_SHORT: 1237 case JIT_TYPE_USHORT: 1238 return small_base + 1; 1239 1240 case JIT_TYPE_INT: 1241 case JIT_TYPE_UINT: 1242 return base_opcode + 2; 1243 1244 case JIT_TYPE_LONG: 1245 case JIT_TYPE_ULONG: 1246 return base_opcode + 3; 1247 1248 case JIT_TYPE_FLOAT32: 1249 return base_opcode + 4; 1250 1251 case JIT_TYPE_FLOAT64: 1252 return base_opcode + 5; 1253 1254 case JIT_TYPE_NFLOAT: 1255 return base_opcode + 6; 1256 1257 case JIT_TYPE_STRUCT: 1258 case JIT_TYPE_UNION: 1259 return base_opcode + 7; 1260 1261 default: 1262 /* Shouldn't happen, but do something sane anyway */ 1263 return base_opcode + 2; 1264 } 1265 } 1266 1267 /*@ 1268 * @deftypefun int jit_insn_nop (jit_function_t @var{func}) 1269 * Emits "no operation" instruction. You may want to do that if you need 1270 * an empty block to move it with @code{jit_insn_move_blocks_XXX} later. 1271 * If you will not put empty instruction between two labels, both labels 1272 * will point to the same block, and block moving will fail. 1273 * @end deftypefun 1274 @*/ 1275 int 1276 jit_insn_nop(jit_function_t func) 1277 { 1278 /* Ensure that we have a function builder */ 1279 if(!_jit_function_ensure_builder(func)) 1280 { 1281 return 0; 1282 } 1283 1284 /* Add a new no-op instruction */ 1285 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 1286 if(!insn) 1287 { 1288 return 0; 1289 } 1290 insn->opcode = JIT_OP_NOP; 1291 1292 return 1; 1293 } 1294 1295 /*@ 1296 * @deftypefun jit_value_t jit_insn_load (jit_function_t @var{func}, jit_value_t @var{value}) 1297 * Load the contents of @var{value} into a new temporary, essentially 1298 * duplicating the value. Constants are not duplicated. 1299 * @end deftypefun 1300 @*/ 1301 jit_value_t 1302 jit_insn_load(jit_function_t func, jit_value_t value) 1303 { 1304 if(value->is_constant) 1305 { 1306 return value; 1307 } 1308 1309 int opcode = _jit_load_opcode(JIT_OP_COPY_LOAD_SBYTE, value->type); 1310 if(opcode == 0) 1311 { 1312 return 0; 1313 } 1314 return apply_unary(func, opcode, value, value->type); 1315 } 1316 1317 /*@ 1318 * @deftypefun jit_value_t jit_insn_dup (jit_function_t @var{func}, jit_value_t @var{value}) 1319 * This is the same as @code{jit_insn_load}, but the name may better 1320 * reflect how it is used in some front ends. 1321 * @end deftypefun 1322 @*/ 1323 jit_value_t 1324 jit_insn_dup(jit_function_t func, jit_value_t value) 1325 { 1326 return jit_insn_load(func, value); 1327 } 1328 1329 /*@ 1330 * @deftypefun void jit_insn_store (jit_function_t @var{func}, jit_value_t @var{dest}, jit_value_t @var{value}) 1331 * Store the contents of @var{value} at the location referred to by 1332 * @var{dest}. The @var{dest} should be a @code{jit_value_t} representing a 1333 * local variable or temporary. Use @code{jit_insn_store_relative} to store 1334 * to a location referred to by a pointer. 1335 * @end deftypefun 1336 @*/ 1337 int 1338 jit_insn_store(jit_function_t func, jit_value_t dest, jit_value_t value) 1339 { 1340 /* Ensure that we have a function builder */ 1341 if(!_jit_function_ensure_builder(func)) 1342 { 1343 return 0; 1344 } 1345 1346 value = jit_insn_convert(func, value, dest->type, 0); 1347 if(!value) 1348 { 1349 return 0; 1350 } 1351 1352 int opcode = _jit_store_opcode(JIT_OP_COPY_INT, JIT_OP_COPY_STORE_BYTE, dest->type); 1353 if(opcode == 0) 1354 { 1355 return 0; 1356 } 1357 1358 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 1359 if(!insn) 1360 { 1361 return 0; 1362 } 1363 insn->opcode = (short) opcode; 1364 insn->dest = dest; 1365 jit_value_ref(func, dest); 1366 insn->value1 = value; 1367 jit_value_ref(func, value); 1368 1369 return 1; 1370 } 1371 1372 /* 1373 * Scan back through the current block, looking for an address instruction that 1374 * involves "value" as its destination. Returns NULL if no such instruction was 1375 * found, or it is blocked by a later use of "value". 1376 * 1377 * The instruction found may then be combined into a new single instruction with 1378 * the following "load_relative", "store_relative", or another "relative_add". 1379 * 1380 * For instance, consider the code like this: 1381 * 1382 * i) y = address_of(x) 1383 * ... 1384 * j) z = add_relative(y, a) 1385 * 1386 * Let's suppose that we need to add a "store_realtive(z, b, v)" instruction. 1387 * The "find_base_insn()" call will return the instruction "j" and we will be 1388 * able to emit the instruction "store_relative(y, a + b, v)" instead. If "z" 1389 * is not used elsewhere then "j" will be optimized away by the dead code 1390 * elimination pass. 1391 * 1392 * Repetitive use of this procedure for a chain of "add_relative" instructions 1393 * converts it into a series of indpenedent instructions each using the very 1394 * first address in the chain as its base. Therefore regardless of the initial 1395 * chain length it is always enough to make single "find_base_insn()" call to 1396 * get the base address of the entire chain (think induction). 1397 * 1398 * Note that in this situation the second "find_base_insn()" call will return 1399 * the instruction "i" that obtains the base address as the address of a local 1400 * frame variable. This instruction is a candidate for being moved down to 1401 * where the "load_relative" or "store_relative" occurs. This might make it 1402 * easier for the code generator to handle field accesses whitin local 1403 * variables. 1404 * 1405 * The "plast" argument indicates if the found instruction is already the last 1406 * one, so there is no need to move it down. 1407 */ 1408 static jit_insn_t 1409 find_base_insn(jit_function_t func, jit_insn_iter_t iter, jit_value_t value, int *plast) 1410 { 1411 /* The "value" could be vulnerable to aliasing effects so we cannot 1412 optimize it */ 1413 if(value->is_addressable || value->is_volatile) 1414 { 1415 return 0; 1416 } 1417 1418 /* We are about to check the last instruction before the current one */ 1419 int last = 1; 1420 1421 /* Iterate back through the block looking for a suitable instruction */ 1422 jit_insn_t insn; 1423 while((insn = jit_insn_iter_previous(&iter)) != 0) 1424 { 1425 /* This instruction uses "value" in some way */ 1426 if(insn->dest == value) 1427 { 1428 /* This is the instruction we were looking for */ 1429 if(insn->opcode == JIT_OP_ADDRESS_OF) 1430 { 1431 *plast = last; 1432 return insn; 1433 } 1434 if(insn->opcode == JIT_OP_ADD_RELATIVE) 1435 { 1436 value = insn->value1; 1437 if(value->is_addressable || value->is_volatile) 1438 { 1439 return 0; 1440 } 1441 1442 /* Scan forwards to ensure that "insn->value1" 1443 is not modified anywhere in the instructions 1444 that follow */ 1445 jit_insn_iter_t iter2 = iter; 1446 jit_insn_iter_next(&iter2); 1447 jit_insn_t insn2; 1448 while((insn2 = jit_insn_iter_next(&iter2)) != 0) 1449 { 1450 if(insn2->dest == value 1451 && (insn2->flags & JIT_INSN_DEST_IS_VALUE) == 0) 1452 { 1453 return 0; 1454 } 1455 } 1456 1457 *plast = last; 1458 return insn; 1459 } 1460 1461 /* Oops. This instruction modifies "value" and blocks 1462 any previous address_of or add_relative instructions */ 1463 if((insn->flags & JIT_INSN_DEST_IS_VALUE) == 0) 1464 { 1465 break; 1466 } 1467 } 1468 1469 /* We are to check instructions that preceed the last one */ 1470 last = 0; 1471 } 1472 return 0; 1473 } 1474 1475 /*@ 1476 * @deftypefun jit_value_t jit_insn_load_relative (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{offset}, jit_type_t @var{type}) 1477 * Load a value of the specified @var{type} from the effective address 1478 * @code{(@var{value} + @var{offset})}, where @var{value} is a pointer. 1479 * @end deftypefun 1480 @*/ 1481 jit_value_t 1482 jit_insn_load_relative(jit_function_t func, jit_value_t value, jit_nint offset, jit_type_t type) 1483 { 1484 /* Ensure that we have a function builder */ 1485 if(!_jit_function_ensure_builder(func)) 1486 { 1487 return 0; 1488 } 1489 1490 jit_insn_iter_t iter; 1491 jit_insn_iter_init_last(&iter, func->builder->current_block); 1492 1493 int last; 1494 jit_insn_t insn = find_base_insn(func, iter, value, &last); 1495 if(insn && insn->opcode == JIT_OP_ADD_RELATIVE) 1496 { 1497 /* We have a previous "add_relative" instruction for this 1498 pointer. Adjust the current offset accordingly */ 1499 offset += jit_value_get_nint_constant(insn->value2); 1500 value = insn->value1; 1501 insn = find_base_insn(func, iter, value, &last); 1502 last = 0; 1503 } 1504 if(insn && insn->opcode == JIT_OP_ADDRESS_OF && !last) 1505 { 1506 /* Shift the "address_of" instruction down, to make 1507 it easier for the code generator to handle field 1508 accesses within local and global variables */ 1509 value = jit_insn_address_of(func, insn->value1); 1510 if(!value) 1511 { 1512 return 0; 1513 } 1514 } 1515 1516 int opcode = _jit_load_opcode(JIT_OP_LOAD_RELATIVE_SBYTE, type); 1517 if(opcode == 0) 1518 { 1519 return 0; 1520 } 1521 jit_value_t offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); 1522 if(!offset_value) 1523 { 1524 return 0; 1525 } 1526 return apply_binary(func, opcode, value, offset_value, type); 1527 } 1528 1529 /*@ 1530 * @deftypefun int jit_insn_store_relative (jit_function_t @var{func}, jit_value_t @var{dest}, jit_nint @var{offset}, jit_value_t @var{value}) 1531 * Store @var{value} at the effective address @code{(@var{dest} + @var{offset})}, 1532 * where @var{dest} is a pointer. Returns a non-zero value on success. 1533 * @end deftypefun 1534 @*/ 1535 int 1536 jit_insn_store_relative(jit_function_t func, jit_value_t dest, jit_nint offset, jit_value_t value) 1537 { 1538 /* Ensure that we have a function builder */ 1539 if(!_jit_function_ensure_builder(func)) 1540 { 1541 return 0; 1542 } 1543 1544 jit_insn_iter_t iter; 1545 jit_insn_iter_init_last(&iter, func->builder->current_block); 1546 1547 int last; 1548 jit_insn_t insn = find_base_insn(func, iter, dest, &last); 1549 if(insn && insn->opcode == JIT_OP_ADD_RELATIVE) 1550 { 1551 /* We have a previous "add_relative" instruction for this 1552 pointer. Adjust the current offset accordingly */ 1553 offset += jit_value_get_nint_constant(insn->value2); 1554 dest = insn->value1; 1555 insn = find_base_insn(func, iter, value, &last); 1556 last = 0; 1557 } 1558 if(insn && insn->opcode == JIT_OP_ADDRESS_OF && !last) 1559 { 1560 /* Shift the "address_of" instruction down, to make 1561 it easier for the code generator to handle field 1562 accesses within local and global variables */ 1563 dest = jit_insn_address_of(func, insn->value1); 1564 if(!dest) 1565 { 1566 return 0; 1567 } 1568 } 1569 1570 int opcode = _jit_store_opcode(JIT_OP_STORE_RELATIVE_BYTE, 0, value->type); 1571 if(opcode == 0) 1572 { 1573 return 0; 1574 } 1575 jit_value_t offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); 1576 if(!offset_value) 1577 { 1578 return 0; 1579 } 1580 1581 insn = _jit_block_add_insn(func->builder->current_block); 1582 if(!insn) 1583 { 1584 return 0; 1585 } 1586 insn->opcode = (short) opcode; 1587 insn->flags = JIT_INSN_DEST_IS_VALUE; 1588 insn->dest = dest; 1589 jit_value_ref(func, dest); 1590 insn->value1 = value; 1591 jit_value_ref(func, value); 1592 insn->value2 = offset_value; 1593 1594 return 1; 1595 } 1596 1597 /*@ 1598 * @deftypefun jit_value_t jit_insn_add_relative (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{offset}) 1599 * Add the constant @var{offset} to the specified pointer @var{value}. 1600 * This is functionally identical to calling @code{jit_insn_add}, but 1601 * the JIT can optimize the code better if it knows that the addition 1602 * is being used to perform a relative adjustment on a pointer. 1603 * In particular, multiple relative adjustments on the same pointer 1604 * can be collapsed into a single adjustment. 1605 * @end deftypefun 1606 @*/ 1607 jit_value_t 1608 jit_insn_add_relative(jit_function_t func, jit_value_t value, jit_nint offset) 1609 { 1610 /* Ensure that we have a function builder */ 1611 if(!_jit_function_ensure_builder(func)) 1612 { 1613 return 0; 1614 } 1615 1616 jit_insn_iter_t iter; 1617 jit_insn_iter_init_last(&iter, func->builder->current_block); 1618 1619 int last; 1620 jit_insn_t insn = find_base_insn(func, iter, value, &last); 1621 if(insn && insn->opcode == JIT_OP_ADD_RELATIVE) 1622 { 1623 /* We have a previous "add_relative" instruction for this 1624 pointer. Adjust the current offset accordingly */ 1625 offset += jit_value_get_nint_constant(insn->value2); 1626 value = insn->value1; 1627 } 1628 1629 jit_value_t offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); 1630 if(!offset_value) 1631 { 1632 return 0; 1633 } 1634 return apply_binary(func, JIT_OP_ADD_RELATIVE, value, offset_value, jit_type_void_ptr); 1635 } 1636 1637 static jit_value_t 1638 element_address(jit_function_t func, jit_value_t base, jit_value_t index, jit_nint size) 1639 { 1640 jit_value_t offset_value = jit_value_create_nint_constant(func, jit_type_nint, size); 1641 if(!offset_value) 1642 { 1643 return 0; 1644 } 1645 offset_value = jit_insn_mul(func, index, offset_value); 1646 if(!offset_value) 1647 { 1648 return 0; 1649 } 1650 return jit_insn_add(func, base, offset_value); 1651 } 1652 1653 /*@ 1654 * @deftypefun jit_value_t jit_insn_load_elem (jit_function_t @var{func}, jit_value_t @var{base_addr}, jit_value_t @var{index}, jit_type_t @var{elem_type}) 1655 * Load an element of type @var{elem_type} from position @var{index} within 1656 * the array starting at @var{base_addr}. The effective address of the 1657 * array element is @code{@var{base_addr} + @var{index} * sizeof(@var{elem_type})}. 1658 * @end deftypefun 1659 @*/ 1660 jit_value_t 1661 jit_insn_load_elem(jit_function_t func, jit_value_t base_addr, jit_value_t index, 1662 jit_type_t elem_type) 1663 { 1664 /* Get the size of the element that we are fetching */ 1665 jit_nint size = (jit_nint) jit_type_get_size(elem_type); 1666 1667 /* Convert the index into a native integer */ 1668 index = jit_insn_convert(func, index, jit_type_nint, 0); 1669 if(!index) 1670 { 1671 return 0; 1672 } 1673 1674 /* If the index is constant, then turn this into a relative load */ 1675 if(jit_value_is_constant(index)) 1676 { 1677 size *= jit_value_get_nint_constant(index); 1678 return jit_insn_load_relative(func, base_addr, size, elem_type); 1679 } 1680 1681 /* See if we can use a special-case instruction */ 1682 int opcode = _jit_load_opcode(JIT_OP_LOAD_ELEMENT_SBYTE, elem_type); 1683 if(opcode != 0 && opcode != (JIT_OP_LOAD_ELEMENT_SBYTE + 9)) 1684 { 1685 return apply_binary(func, opcode, base_addr, index, elem_type); 1686 } 1687 1688 /* Calculate the effective address and then use a relative load */ 1689 jit_value_t addr = element_address(func, base_addr, index, size); 1690 if(!addr) 1691 { 1692 return 0; 1693 } 1694 return jit_insn_load_relative(func, addr, 0, elem_type); 1695 } 1696 1697 /*@ 1698 * @deftypefun jit_value_t jit_insn_load_elem_address (jit_function_t @var{func}, jit_value_t @var{base_addr}, jit_value_t @var{index}, jit_type_t @var{elem_type}) 1699 * Load the effective address of an element of type @var{elem_type} at 1700 * position @var{index} within the array starting at @var{base_addr}. 1701 * Essentially, this computes the expression 1702 * @code{@var{base_addr} + @var{index} * sizeof(@var{elem_type})}, but 1703 * may be more efficient than performing the steps with @code{jit_insn_mul} 1704 * and @code{jit_insn_add}. 1705 * @end deftypefun 1706 @*/ 1707 jit_value_t 1708 jit_insn_load_elem_address(jit_function_t func, jit_value_t base_addr, jit_value_t index, 1709 jit_type_t elem_type) 1710 { 1711 jit_nint size = (jit_nint) jit_type_get_size(elem_type); 1712 1713 /* Convert the index into a native integer */ 1714 index = jit_insn_convert(func, index, jit_type_nint, 0); 1715 if(!index) 1716 { 1717 return 0; 1718 } 1719 1720 return element_address(func, base_addr, index, size); 1721 } 1722 1723 /*@ 1724 * @deftypefun int jit_insn_store_elem (jit_function_t @var{func}, jit_value_t @var{base_addr}, jit_value_t @var{index}, jit_value_t @var{value}) 1725 * Store @var{value} at position @var{index} of the array starting at 1726 * @var{base_addr}. The effective address of the storage location is 1727 * @code{@var{base_addr} + @var{index} * sizeof(jit_value_get_type(@var{value}))}. 1728 * @end deftypefun 1729 @*/ 1730 int 1731 jit_insn_store_elem(jit_function_t func, jit_value_t base_addr, jit_value_t index, 1732 jit_value_t value) 1733 { 1734 /* Get the size of the element that we are fetching */ 1735 jit_type_t elem_type = jit_value_get_type(value); 1736 jit_nint size = (jit_nint) jit_type_get_size(elem_type); 1737 1738 /* Convert the index into a native integer */ 1739 index = jit_insn_convert(func, index, jit_type_nint, 0); 1740 if(!index) 1741 { 1742 return 0; 1743 } 1744 1745 /* If the index is constant, then turn this into a relative store */ 1746 if(jit_value_is_constant(index)) 1747 { 1748 return jit_insn_store_relative(func, base_addr, 1749 jit_value_get_nint_constant(index) * size, 1750 value); 1751 } 1752 1753 /* See if we can use a special-case instruction */ 1754 int opcode = _jit_store_opcode(JIT_OP_STORE_ELEMENT_BYTE, 0, elem_type); 1755 if(opcode != 0 && opcode != (JIT_OP_STORE_ELEMENT_BYTE + 7)) 1756 { 1757 return apply_ternary(func, opcode, base_addr, index, value); 1758 } 1759 1760 /* Calculate the effective address and then use a relative store */ 1761 jit_value_t addr = element_address(func, base_addr, index, size); 1762 if(!addr) 1763 { 1764 return 0; 1765 } 1766 return jit_insn_store_relative(func, addr, 0, value); 1767 } 1768 1769 /*@ 1770 * @deftypefun int jit_insn_check_null (jit_function_t @var{func}, jit_value_t @var{value}) 1771 * Check @var{value} to see if it is NULL. If it is, then throw the 1772 * built-in @code{JIT_RESULT_NULL_REFERENCE} exception. 1773 * @end deftypefun 1774 @*/ 1775 int 1776 jit_insn_check_null(jit_function_t func, jit_value_t value) 1777 { 1778 /* Ensure that we have a function builder */ 1779 if(!_jit_function_ensure_builder(func)) 1780 { 1781 return 0; 1782 } 1783 1784 /* Do the check only if the value is no not Null constant */ 1785 if(value->is_nint_constant && value->address != 0) 1786 { 1787 return 1; 1788 } 1789 func->builder->may_throw = 1; 1790 return create_unary_note(func, JIT_OP_CHECK_NULL, value); 1791 } 1792 1793 int 1794 _jit_insn_check_is_redundant(const jit_insn_iter_t *iter) 1795 { 1796 jit_insn_iter_t new_iter = *iter; 1797 /* Back up to find the "check_null" instruction of interest */ 1798 jit_insn_t insn = jit_insn_iter_previous(&new_iter); 1799 jit_value_t value = insn->value1; 1800 1801 /* The value must be temporary or local, and not volatile or addressable. 1802 Otherwise the value could be vulnerable to aliasing side-effects that 1803 could make it NULL again even after we have checked it */ 1804 if(!value->is_temporary || !value->is_local) 1805 { 1806 return 0; 1807 } 1808 if(value->is_volatile || value->is_addressable) 1809 { 1810 return 0; 1811 } 1812 1813 /* Search back for a previous "check_null" instruction */ 1814 while((insn = jit_insn_iter_previous(&new_iter)) != 0) 1815 { 1816 if(insn->opcode == JIT_OP_CHECK_NULL && insn->value1 == value) 1817 { 1818 /* This is the previous "check_null" that we were looking for */ 1819 return 1; 1820 } 1821 if(insn->opcode >= JIT_OP_STORE_RELATIVE_BYTE && 1822 insn->opcode <= JIT_OP_STORE_RELATIVE_STRUCT) 1823 { 1824 /* This stores to the memory referenced by the destination, 1825 not to the destination itself, so it cannot affect "value" */ 1826 continue; 1827 } 1828 if(insn->dest == value) 1829 { 1830 /* The value was used as a destination, so we must check */ 1831 return 0; 1832 } 1833 } 1834 1835 /* There was no previous "check_null" instruction for this value */ 1836 return 0; 1837 } 1838 1839 /*@ 1840 * @deftypefun jit_value_t jit_insn_add (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1841 * Add two values together and return the result in a new temporary value. 1842 * @end deftypefun 1843 @*/ 1844 jit_value_t 1845 jit_insn_add(jit_function_t func, jit_value_t value1, jit_value_t value2) 1846 { 1847 static jit_opcode_descr const add_descr = { 1848 JIT_OP_IADD, 1849 JIT_OP_IADD, 1850 JIT_OP_LADD, 1851 JIT_OP_LADD, 1852 JIT_OP_FADD, 1853 JIT_OP_DADD, 1854 JIT_OP_NFADD, 1855 jit_intrinsic(jit_int_add, descr_i_ii), 1856 jit_intrinsic(jit_uint_add, descr_I_II), 1857 jit_intrinsic(jit_long_add, descr_l_ll), 1858 jit_intrinsic(jit_ulong_add, descr_L_LL), 1859 jit_intrinsic(jit_float32_add, descr_f_ff), 1860 jit_intrinsic(jit_float64_add, descr_d_dd), 1861 jit_intrinsic(jit_nfloat_add, descr_D_DD) 1862 }; 1863 return apply_arith(func, &add_descr, value1, value2, 0, 0, 0); 1864 } 1865 1866 /*@ 1867 * @deftypefun jit_value_t jit_insn_add_ovf (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1868 * Add two values together and return the result in a new temporary value. 1869 * Throw an exception if overflow occurs. 1870 * @end deftypefun 1871 @*/ 1872 jit_value_t 1873 jit_insn_add_ovf(jit_function_t func, jit_value_t value1, jit_value_t value2) 1874 { 1875 static jit_opcode_descr const add_ovf_descr = { 1876 JIT_OP_IADD_OVF, 1877 JIT_OP_IADD_OVF_UN, 1878 JIT_OP_LADD_OVF, 1879 JIT_OP_LADD_OVF_UN, 1880 JIT_OP_FADD, 1881 JIT_OP_DADD, 1882 JIT_OP_NFADD, 1883 jit_intrinsic(jit_int_add_ovf, descr_e_pi_ii), 1884 jit_intrinsic(jit_uint_add_ovf, descr_e_pI_II), 1885 jit_intrinsic(jit_long_add_ovf, descr_e_pl_ll), 1886 jit_intrinsic(jit_ulong_add_ovf, descr_e_pL_LL), 1887 jit_intrinsic(jit_float32_add, descr_f_ff), 1888 jit_intrinsic(jit_float64_add, descr_d_dd), 1889 jit_intrinsic(jit_nfloat_add, descr_D_DD) 1890 }; 1891 return apply_arith(func, &add_ovf_descr, value1, value2, 0, 0, 1); 1892 } 1893 1894 /*@ 1895 * @deftypefun jit_value_t jit_insn_sub (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1896 * Subtract two values and return the result in a new temporary value. 1897 * @end deftypefun 1898 @*/ 1899 jit_value_t 1900 jit_insn_sub(jit_function_t func, jit_value_t value1, jit_value_t value2) 1901 { 1902 static jit_opcode_descr const sub_descr = { 1903 JIT_OP_ISUB, 1904 JIT_OP_ISUB, 1905 JIT_OP_LSUB, 1906 JIT_OP_LSUB, 1907 JIT_OP_FSUB, 1908 JIT_OP_DSUB, 1909 JIT_OP_NFSUB, 1910 jit_intrinsic(jit_int_sub, descr_i_ii), 1911 jit_intrinsic(jit_uint_sub, descr_I_II), 1912 jit_intrinsic(jit_long_sub, descr_l_ll), 1913 jit_intrinsic(jit_ulong_sub, descr_L_LL), 1914 jit_intrinsic(jit_float32_sub, descr_f_ff), 1915 jit_intrinsic(jit_float64_sub, descr_d_dd), 1916 jit_intrinsic(jit_nfloat_sub, descr_D_DD) 1917 }; 1918 return apply_arith(func, &sub_descr, value1, value2, 0, 0, 0); 1919 } 1920 1921 /*@ 1922 * @deftypefun jit_value_t jit_insn_sub_ovf (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1923 * Subtract two values and return the result in a new temporary value. 1924 * Throw an exception if overflow occurs. 1925 * @end deftypefun 1926 @*/ 1927 jit_value_t 1928 jit_insn_sub_ovf(jit_function_t func, jit_value_t value1, jit_value_t value2) 1929 { 1930 static jit_opcode_descr const sub_ovf_descr = { 1931 JIT_OP_ISUB_OVF, 1932 JIT_OP_ISUB_OVF_UN, 1933 JIT_OP_LSUB_OVF, 1934 JIT_OP_LSUB_OVF_UN, 1935 JIT_OP_FSUB, 1936 JIT_OP_DSUB, 1937 JIT_OP_NFSUB, 1938 jit_intrinsic(jit_int_sub_ovf, descr_e_pi_ii), 1939 jit_intrinsic(jit_uint_sub_ovf, descr_e_pI_II), 1940 jit_intrinsic(jit_long_sub_ovf, descr_e_pl_ll), 1941 jit_intrinsic(jit_ulong_sub_ovf, descr_e_pL_LL), 1942 jit_intrinsic(jit_float32_sub, descr_f_ff), 1943 jit_intrinsic(jit_float64_sub, descr_d_dd), 1944 jit_intrinsic(jit_nfloat_sub, descr_D_DD) 1945 }; 1946 return apply_arith(func, &sub_ovf_descr, value1, value2, 0, 0, 1); 1947 } 1948 1949 /*@ 1950 * @deftypefun jit_value_t jit_insn_mul (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1951 * Multiply two values and return the result in a new temporary value. 1952 * @end deftypefun 1953 @*/ 1954 jit_value_t 1955 jit_insn_mul(jit_function_t func, jit_value_t value1, jit_value_t value2) 1956 { 1957 static jit_opcode_descr const mul_descr = { 1958 JIT_OP_IMUL, 1959 JIT_OP_IMUL, 1960 JIT_OP_LMUL, 1961 JIT_OP_LMUL, 1962 JIT_OP_FMUL, 1963 JIT_OP_DMUL, 1964 JIT_OP_NFMUL, 1965 jit_intrinsic(jit_int_mul, descr_i_ii), 1966 jit_intrinsic(jit_uint_mul, descr_I_II), 1967 jit_intrinsic(jit_long_mul, descr_l_ll), 1968 jit_intrinsic(jit_ulong_mul, descr_L_LL), 1969 jit_intrinsic(jit_float32_mul, descr_f_ff), 1970 jit_intrinsic(jit_float64_mul, descr_d_dd), 1971 jit_intrinsic(jit_nfloat_mul, descr_D_DD) 1972 }; 1973 return apply_arith(func, &mul_descr, value1, value2, 0, 0, 0); 1974 } 1975 1976 /*@ 1977 * @deftypefun jit_value_t jit_insn_mul_ovf (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 1978 * Multiply two values and return the result in a new temporary value. 1979 * Throw an exception if overflow occurs. 1980 * @end deftypefun 1981 @*/ 1982 jit_value_t 1983 jit_insn_mul_ovf(jit_function_t func, jit_value_t value1, jit_value_t value2) 1984 { 1985 static jit_opcode_descr const mul_ovf_descr = { 1986 JIT_OP_IMUL_OVF, 1987 JIT_OP_IMUL_OVF_UN, 1988 JIT_OP_LMUL_OVF, 1989 JIT_OP_LMUL_OVF_UN, 1990 JIT_OP_FMUL, 1991 JIT_OP_DMUL, 1992 JIT_OP_NFMUL, 1993 jit_intrinsic(jit_int_mul_ovf, descr_e_pi_ii), 1994 jit_intrinsic(jit_uint_mul_ovf, descr_e_pI_II), 1995 jit_intrinsic(jit_long_mul_ovf, descr_e_pl_ll), 1996 jit_intrinsic(jit_ulong_mul_ovf, descr_e_pL_LL), 1997 jit_intrinsic(jit_float32_mul, descr_f_ff), 1998 jit_intrinsic(jit_float64_mul, descr_d_dd), 1999 jit_intrinsic(jit_nfloat_mul, descr_D_DD) 2000 }; 2001 return apply_arith(func, &mul_ovf_descr, value1, value2, 0, 0, 1); 2002 } 2003 2004 /*@ 2005 * @deftypefun jit_value_t jit_insn_div (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2006 * Divide two values and return the quotient in a new temporary value. 2007 * Throws an exception on division by zero or arithmetic error 2008 * (an arithmetic error is one where the minimum possible signed 2009 * integer value is divided by -1). 2010 * @end deftypefun 2011 @*/ 2012 jit_value_t 2013 jit_insn_div(jit_function_t func, jit_value_t value1, jit_value_t value2) 2014 { 2015 static jit_opcode_descr const div_descr = { 2016 JIT_OP_IDIV, 2017 JIT_OP_IDIV_UN, 2018 JIT_OP_LDIV, 2019 JIT_OP_LDIV_UN, 2020 JIT_OP_FDIV, 2021 JIT_OP_DDIV, 2022 JIT_OP_NFDIV, 2023 jit_intrinsic(jit_int_div, descr_e_pi_ii), 2024 jit_intrinsic(jit_uint_div, descr_e_pI_II), 2025 jit_intrinsic(jit_long_div, descr_e_pl_ll), 2026 jit_intrinsic(jit_ulong_div, descr_e_pL_LL), 2027 jit_intrinsic(jit_float32_div, descr_f_ff), 2028 jit_intrinsic(jit_float64_div, descr_d_dd), 2029 jit_intrinsic(jit_nfloat_div, descr_D_DD) 2030 }; 2031 return apply_arith(func, &div_descr, value1, value2, 0, 0, 0); 2032 } 2033 2034 /*@ 2035 * @deftypefun jit_value_t jit_insn_rem (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2036 * Divide two values and return the remainder in a new temporary value. 2037 * Throws an exception on division by zero or arithmetic error 2038 * (an arithmetic error is one where the minimum possible signed 2039 * integer value is divided by -1). 2040 * @end deftypefun 2041 @*/ 2042 jit_value_t 2043 jit_insn_rem(jit_function_t func, jit_value_t value1, jit_value_t value2) 2044 { 2045 static jit_opcode_descr const rem_descr = { 2046 JIT_OP_IREM, 2047 JIT_OP_IREM_UN, 2048 JIT_OP_LREM, 2049 JIT_OP_LREM_UN, 2050 JIT_OP_FREM, 2051 JIT_OP_DREM, 2052 JIT_OP_NFREM, 2053 jit_intrinsic(jit_int_rem, descr_e_pi_ii), 2054 jit_intrinsic(jit_uint_rem, descr_e_pI_II), 2055 jit_intrinsic(jit_long_rem, descr_e_pl_ll), 2056 jit_intrinsic(jit_ulong_rem, descr_e_pL_LL), 2057 jit_intrinsic(jit_float32_rem, descr_f_ff), 2058 jit_intrinsic(jit_float64_rem, descr_d_dd), 2059 jit_intrinsic(jit_nfloat_rem, descr_D_DD) 2060 }; 2061 return apply_arith(func, &rem_descr, value1, value2, 0, 0, 0); 2062 } 2063 2064 /*@ 2065 * @deftypefun jit_value_t jit_insn_rem_ieee (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2066 * Divide two values and return the remainder in a new temporary value. 2067 * Throws an exception on division by zero or arithmetic error 2068 * (an arithmetic error is one where the minimum possible signed 2069 * integer value is divided by -1). This function is identical to 2070 * @code{jit_insn_rem}, except that it uses IEEE rules for computing 2071 * the remainder of floating-point values. 2072 * @end deftypefun 2073 @*/ 2074 jit_value_t 2075 jit_insn_rem_ieee(jit_function_t func, jit_value_t value1, jit_value_t value2) 2076 { 2077 static jit_opcode_descr const rem_ieee_descr = { 2078 JIT_OP_IREM, 2079 JIT_OP_IREM_UN, 2080 JIT_OP_LREM, 2081 JIT_OP_LREM_UN, 2082 JIT_OP_FREM_IEEE, 2083 JIT_OP_DREM_IEEE, 2084 JIT_OP_NFREM_IEEE, 2085 jit_intrinsic(jit_int_rem, descr_e_pi_ii), 2086 jit_intrinsic(jit_uint_rem, descr_e_pI_II), 2087 jit_intrinsic(jit_long_rem, descr_e_pl_ll), 2088 jit_intrinsic(jit_ulong_rem, descr_e_pL_LL), 2089 jit_intrinsic(jit_float32_ieee_rem, descr_f_ff), 2090 jit_intrinsic(jit_float64_ieee_rem, descr_d_dd), 2091 jit_intrinsic(jit_nfloat_ieee_rem, descr_D_DD) 2092 }; 2093 return apply_arith(func, &rem_ieee_descr, value1, value2, 0, 0, 0); 2094 } 2095 2096 /*@ 2097 * @deftypefun jit_value_t jit_insn_neg (jit_function_t @var{func}, jit_value_t @var{value1}) 2098 * Negate a value and return the result in a new temporary value. 2099 * @end deftypefun 2100 @*/ 2101 jit_value_t 2102 jit_insn_neg(jit_function_t func, jit_value_t value) 2103 { 2104 static jit_opcode_descr const neg_descr = { 2105 JIT_OP_INEG, 2106 JIT_OP_INEG, 2107 JIT_OP_LNEG, 2108 JIT_OP_LNEG, 2109 JIT_OP_FNEG, 2110 JIT_OP_DNEG, 2111 JIT_OP_NFNEG, 2112 jit_intrinsic(jit_int_neg, descr_i_i), 2113 jit_intrinsic(jit_uint_neg, descr_I_I), 2114 jit_intrinsic(jit_long_neg, descr_l_l), 2115 jit_intrinsic(jit_ulong_neg, descr_L_L), 2116 jit_intrinsic(jit_float32_neg, descr_f_f), 2117 jit_intrinsic(jit_float64_neg, descr_d_d), 2118 jit_intrinsic(jit_nfloat_neg, descr_D_D) 2119 }; 2120 2121 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 2122 2123 int oper; 2124 switch (type->kind) 2125 { 2126 default: /* Shouldn't happen */ 2127 case JIT_TYPE_INT: 2128 oper = neg_descr.ioper; 2129 break; 2130 case JIT_TYPE_UINT: 2131 type = jit_type_int; 2132 oper = neg_descr.ioper; 2133 break; 2134 case JIT_TYPE_LONG: 2135 oper = neg_descr.loper; 2136 break; 2137 case JIT_TYPE_ULONG: 2138 type = jit_type_long; 2139 oper = neg_descr.loper; 2140 break; 2141 case JIT_TYPE_FLOAT32: 2142 oper = neg_descr.foper; 2143 break; 2144 case JIT_TYPE_FLOAT64: 2145 oper = neg_descr.doper; 2146 break; 2147 case JIT_TYPE_NFLOAT: 2148 oper = neg_descr.nfoper; 2149 break; 2150 } 2151 2152 value = jit_insn_convert(func, value, type, 0); 2153 if(!value) 2154 { 2155 return 0; 2156 } 2157 if(jit_value_is_constant(value)) 2158 { 2159 jit_value_t result = _jit_opcode_apply_unary(func, oper, value, type); 2160 if(result) 2161 { 2162 return result; 2163 } 2164 } 2165 2166 if(!_jit_opcode_is_supported(oper)) 2167 { 2168 return apply_intrinsic(func, &neg_descr, value, 0, type); 2169 } 2170 return apply_unary(func, oper, value, type); 2171 } 2172 2173 /*@ 2174 * @deftypefun jit_value_t jit_insn_and (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2175 * Bitwise AND two values and return the result in a new temporary value. 2176 * @end deftypefun 2177 @*/ 2178 jit_value_t 2179 jit_insn_and(jit_function_t func, jit_value_t value1, jit_value_t value2) 2180 { 2181 static jit_opcode_descr const and_descr = { 2182 JIT_OP_IAND, 2183 JIT_OP_IAND, 2184 JIT_OP_LAND, 2185 JIT_OP_LAND, 2186 0, 0, 0, 2187 jit_intrinsic(jit_int_and, descr_i_ii), 2188 jit_intrinsic(jit_uint_and, descr_I_II), 2189 jit_intrinsic(jit_long_and, descr_l_ll), 2190 jit_intrinsic(jit_ulong_and, descr_L_LL), 2191 jit_no_intrinsic, 2192 jit_no_intrinsic, 2193 jit_no_intrinsic 2194 }; 2195 return apply_arith(func, &and_descr, value1, value2, 1, 0, 0); 2196 } 2197 2198 /*@ 2199 * @deftypefun jit_value_t jit_insn_or (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2200 * Bitwise OR two values and return the result in a new temporary value. 2201 * @end deftypefun 2202 @*/ 2203 jit_value_t 2204 jit_insn_or(jit_function_t func, jit_value_t value1, jit_value_t value2) 2205 { 2206 static jit_opcode_descr const or_descr = { 2207 JIT_OP_IOR, 2208 JIT_OP_IOR, 2209 JIT_OP_LOR, 2210 JIT_OP_LOR, 2211 0, 0, 0, 2212 jit_intrinsic(jit_int_or, descr_i_ii), 2213 jit_intrinsic(jit_uint_or, descr_I_II), 2214 jit_intrinsic(jit_long_or, descr_l_ll), 2215 jit_intrinsic(jit_ulong_or, descr_L_LL), 2216 jit_no_intrinsic, 2217 jit_no_intrinsic, 2218 jit_no_intrinsic 2219 }; 2220 return apply_arith(func, &or_descr, value1, value2, 1, 0, 0); 2221 } 2222 2223 /*@ 2224 * @deftypefun jit_value_t jit_insn_xor (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2225 * Bitwise XOR two values and return the result in a new temporary value. 2226 * @end deftypefun 2227 @*/ 2228 jit_value_t 2229 jit_insn_xor(jit_function_t func, jit_value_t value1, jit_value_t value2) 2230 { 2231 static jit_opcode_descr const xor_descr = { 2232 JIT_OP_IXOR, 2233 JIT_OP_IXOR, 2234 JIT_OP_LXOR, 2235 JIT_OP_LXOR, 2236 0, 0, 0, 2237 jit_intrinsic(jit_int_xor, descr_i_ii), 2238 jit_intrinsic(jit_uint_xor, descr_I_II), 2239 jit_intrinsic(jit_long_xor, descr_l_ll), 2240 jit_intrinsic(jit_ulong_xor, descr_L_LL), 2241 jit_no_intrinsic, 2242 jit_no_intrinsic, 2243 jit_no_intrinsic 2244 }; 2245 return apply_arith(func, &xor_descr, value1, value2, 1, 0, 0); 2246 } 2247 2248 /*@ 2249 * @deftypefun jit_value_t jit_insn_not (jit_function_t @var{func}, jit_value_t @var{value1}) 2250 * Bitwise NOT a value and return the result in a new temporary value. 2251 * @end deftypefun 2252 @*/ 2253 jit_value_t 2254 jit_insn_not(jit_function_t func, jit_value_t value) 2255 { 2256 static jit_opcode_descr const not_descr = { 2257 JIT_OP_INOT, 2258 JIT_OP_INOT, 2259 JIT_OP_LNOT, 2260 JIT_OP_LNOT, 2261 0, 0, 0, 2262 jit_intrinsic(jit_int_not, descr_i_i), 2263 jit_intrinsic(jit_uint_not, descr_I_I), 2264 jit_intrinsic(jit_long_not, descr_l_l), 2265 jit_intrinsic(jit_ulong_not, descr_L_L), 2266 jit_no_intrinsic, 2267 jit_no_intrinsic, 2268 jit_no_intrinsic 2269 }; 2270 return apply_unary_arith(func, ¬_descr, value, 1, 0, 0); 2271 } 2272 2273 /*@ 2274 * @deftypefun jit_value_t jit_insn_shl (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2275 * Perform a bitwise left shift on two values and return the 2276 * result in a new temporary value. 2277 * @end deftypefun 2278 @*/ 2279 jit_value_t 2280 jit_insn_shl(jit_function_t func, jit_value_t value1, jit_value_t value2) 2281 { 2282 static jit_opcode_descr const shl_descr = { 2283 JIT_OP_ISHL, 2284 JIT_OP_ISHL, 2285 JIT_OP_LSHL, 2286 JIT_OP_LSHL, 2287 0, 0, 0, 2288 jit_intrinsic(jit_int_shl, descr_i_iI), 2289 jit_intrinsic(jit_uint_shl, descr_I_II), 2290 jit_intrinsic(jit_long_shl, descr_l_lI), 2291 jit_intrinsic(jit_ulong_shl, descr_L_LI), 2292 jit_no_intrinsic, 2293 jit_no_intrinsic, 2294 jit_no_intrinsic 2295 }; 2296 return apply_shift(func, &shl_descr, value1, value2); 2297 } 2298 2299 /*@ 2300 * @deftypefun jit_value_t jit_insn_shr (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2301 * Perform a bitwise right shift on two values and return the 2302 * result in a new temporary value. This performs a signed shift 2303 * on signed operators, and an unsigned shift on unsigned operands. 2304 * @end deftypefun 2305 @*/ 2306 jit_value_t 2307 jit_insn_shr(jit_function_t func, jit_value_t value1, jit_value_t value2) 2308 { 2309 static jit_opcode_descr const shr_descr = { 2310 JIT_OP_ISHR, 2311 JIT_OP_ISHR_UN, 2312 JIT_OP_LSHR, 2313 JIT_OP_LSHR_UN, 2314 0, 0, 0, 2315 jit_intrinsic(jit_int_shr, descr_i_iI), 2316 jit_intrinsic(jit_uint_shr, descr_I_II), 2317 jit_intrinsic(jit_long_shr, descr_l_lI), 2318 jit_intrinsic(jit_ulong_shr, descr_L_LI), 2319 jit_no_intrinsic, 2320 jit_no_intrinsic, 2321 jit_no_intrinsic 2322 }; 2323 return apply_shift(func, &shr_descr, value1, value2); 2324 } 2325 2326 /*@ 2327 * @deftypefun jit_value_t jit_insn_ushr (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2328 * Perform a bitwise right shift on two values and return the 2329 * result in a new temporary value. This performs an unsigned 2330 * shift on both signed and unsigned operands. 2331 * @end deftypefun 2332 @*/ 2333 jit_value_t 2334 jit_insn_ushr(jit_function_t func, jit_value_t value1, jit_value_t value2) 2335 { 2336 static jit_opcode_descr const ushr_descr = { 2337 JIT_OP_ISHR_UN, 2338 JIT_OP_ISHR_UN, 2339 JIT_OP_LSHR_UN, 2340 JIT_OP_LSHR_UN, 2341 0, 0, 0, 2342 jit_intrinsic(jit_uint_shr, descr_I_II), 2343 jit_intrinsic(jit_uint_shr, descr_I_II), 2344 jit_intrinsic(jit_ulong_shr, descr_L_LI), 2345 jit_intrinsic(jit_ulong_shr, descr_L_LI), 2346 jit_no_intrinsic, 2347 jit_no_intrinsic, 2348 jit_no_intrinsic 2349 }; 2350 return apply_shift(func, &ushr_descr, value1, value2); 2351 } 2352 2353 /*@ 2354 * @deftypefun jit_value_t jit_insn_sshr (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2355 * Perform a bitwise right shift on two values and return the 2356 * result in a new temporary value. This performs an signed 2357 * shift on both signed and unsigned operands. 2358 * @end deftypefun 2359 @*/ 2360 jit_value_t 2361 jit_insn_sshr(jit_function_t func, jit_value_t value1, jit_value_t value2) 2362 { 2363 static jit_opcode_descr const sshr_descr = { 2364 JIT_OP_ISHR, 2365 JIT_OP_ISHR, 2366 JIT_OP_LSHR, 2367 JIT_OP_LSHR, 2368 0, 0, 0, 2369 jit_intrinsic(jit_int_shr, descr_i_iI), 2370 jit_intrinsic(jit_int_shr, descr_i_iI), 2371 jit_intrinsic(jit_long_shr, descr_l_lI), 2372 jit_intrinsic(jit_long_shr, descr_l_lI), 2373 jit_no_intrinsic, 2374 jit_no_intrinsic, 2375 jit_no_intrinsic 2376 }; 2377 return apply_shift(func, &sshr_descr, value1, value2); 2378 } 2379 2380 /*@ 2381 * @deftypefun jit_value_t jit_insn_eq (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2382 * Compare two values for equality and return the result 2383 * in a new temporary value. 2384 * @end deftypefun 2385 @*/ 2386 jit_value_t 2387 jit_insn_eq(jit_function_t func, jit_value_t value1, jit_value_t value2) 2388 { 2389 static jit_opcode_descr const eq_descr = { 2390 JIT_OP_IEQ, 2391 JIT_OP_IEQ, 2392 JIT_OP_LEQ, 2393 JIT_OP_LEQ, 2394 JIT_OP_FEQ, 2395 JIT_OP_DEQ, 2396 JIT_OP_NFEQ, 2397 jit_intrinsic(jit_int_eq, descr_i_ii), 2398 jit_intrinsic(jit_uint_eq, descr_i_II), 2399 jit_intrinsic(jit_long_eq, descr_i_ll), 2400 jit_intrinsic(jit_ulong_eq, descr_i_LL), 2401 jit_intrinsic(jit_float32_eq, descr_i_ff), 2402 jit_intrinsic(jit_float64_eq, descr_i_dd), 2403 jit_intrinsic(jit_nfloat_eq, descr_i_DD) 2404 }; 2405 return apply_compare(func, &eq_descr, value1, value2, 0); 2406 } 2407 2408 /*@ 2409 * @deftypefun jit_value_t jit_insn_ne (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2410 * Compare two values for inequality and return the result 2411 * in a new temporary value. 2412 * @end deftypefun 2413 @*/ 2414 jit_value_t 2415 jit_insn_ne(jit_function_t func, jit_value_t value1, jit_value_t value2) 2416 { 2417 static jit_opcode_descr const ne_descr = { 2418 JIT_OP_INE, 2419 JIT_OP_INE, 2420 JIT_OP_LNE, 2421 JIT_OP_LNE, 2422 JIT_OP_FNE, 2423 JIT_OP_DNE, 2424 JIT_OP_NFNE, 2425 jit_intrinsic(jit_int_ne, descr_i_ii), 2426 jit_intrinsic(jit_uint_ne, descr_i_II), 2427 jit_intrinsic(jit_long_ne, descr_i_ll), 2428 jit_intrinsic(jit_ulong_ne, descr_i_LL), 2429 jit_intrinsic(jit_float32_ne, descr_i_ff), 2430 jit_intrinsic(jit_float64_ne, descr_i_dd), 2431 jit_intrinsic(jit_nfloat_ne, descr_i_DD) 2432 }; 2433 return apply_compare(func, &ne_descr, value1, value2, 0); 2434 } 2435 2436 /*@ 2437 * @deftypefun jit_value_t jit_insn_lt (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2438 * Compare two values for less than and return the result 2439 * in a new temporary value. 2440 * @end deftypefun 2441 @*/ 2442 jit_value_t 2443 jit_insn_lt(jit_function_t func, jit_value_t value1, jit_value_t value2) 2444 { 2445 static jit_opcode_descr const lt_descr = { 2446 JIT_OP_ILT, 2447 JIT_OP_ILT_UN, 2448 JIT_OP_LLT, 2449 JIT_OP_LLT_UN, 2450 JIT_OP_FLT, 2451 JIT_OP_DLT, 2452 JIT_OP_NFLT, 2453 jit_intrinsic(jit_int_lt, descr_i_ii), 2454 jit_intrinsic(jit_uint_lt, descr_i_II), 2455 jit_intrinsic(jit_long_lt, descr_i_ll), 2456 jit_intrinsic(jit_ulong_lt, descr_i_LL), 2457 jit_intrinsic(jit_float32_lt, descr_i_ff), 2458 jit_intrinsic(jit_float64_lt, descr_i_dd), 2459 jit_intrinsic(jit_nfloat_lt, descr_i_DD) 2460 }; 2461 return apply_compare(func, <_descr, value1, value2, 0); 2462 } 2463 2464 /*@ 2465 * @deftypefun jit_value_t jit_insn_le (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2466 * Compare two values for less than or equal and return the result 2467 * in a new temporary value. 2468 * @end deftypefun 2469 @*/ 2470 jit_value_t 2471 jit_insn_le(jit_function_t func, jit_value_t value1, jit_value_t value2) 2472 { 2473 static jit_opcode_descr const le_descr = { 2474 JIT_OP_ILE, 2475 JIT_OP_ILE_UN, 2476 JIT_OP_LLE, 2477 JIT_OP_LLE_UN, 2478 JIT_OP_FLE, 2479 JIT_OP_DLE, 2480 JIT_OP_NFLE, 2481 jit_intrinsic(jit_int_le, descr_i_ii), 2482 jit_intrinsic(jit_uint_le, descr_i_II), 2483 jit_intrinsic(jit_long_le, descr_i_ll), 2484 jit_intrinsic(jit_ulong_le, descr_i_LL), 2485 jit_intrinsic(jit_float32_le, descr_i_ff), 2486 jit_intrinsic(jit_float64_le, descr_i_dd), 2487 jit_intrinsic(jit_nfloat_le, descr_i_DD) 2488 }; 2489 return apply_compare(func, &le_descr, value1, value2, 0); 2490 } 2491 2492 /*@ 2493 * @deftypefun jit_value_t jit_insn_gt (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2494 * Compare two values for greater than and return the result 2495 * in a new temporary value. 2496 * @end deftypefun 2497 @*/ 2498 jit_value_t 2499 jit_insn_gt(jit_function_t func, jit_value_t value1, jit_value_t value2) 2500 { 2501 static jit_opcode_descr const gt_descr = { 2502 JIT_OP_IGT, 2503 JIT_OP_IGT_UN, 2504 JIT_OP_LGT, 2505 JIT_OP_LGT_UN, 2506 JIT_OP_FGT, 2507 JIT_OP_DGT, 2508 JIT_OP_NFGT, 2509 jit_intrinsic(jit_int_gt, descr_i_ii), 2510 jit_intrinsic(jit_uint_gt, descr_i_II), 2511 jit_intrinsic(jit_long_gt, descr_i_ll), 2512 jit_intrinsic(jit_ulong_gt, descr_i_LL), 2513 jit_intrinsic(jit_float32_gt, descr_i_ff), 2514 jit_intrinsic(jit_float64_gt, descr_i_dd), 2515 jit_intrinsic(jit_nfloat_gt, descr_i_DD) 2516 }; 2517 return apply_compare(func, >_descr, value1, value2, 0); 2518 } 2519 2520 /*@ 2521 * @deftypefun jit_value_t jit_insn_ge (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2522 * Compare two values for greater than or equal and return the result 2523 * in a new temporary value. 2524 * @end deftypefun 2525 @*/ 2526 jit_value_t 2527 jit_insn_ge(jit_function_t func, jit_value_t value1, jit_value_t value2) 2528 { 2529 static jit_opcode_descr const ge_descr = { 2530 JIT_OP_IGE, 2531 JIT_OP_IGE_UN, 2532 JIT_OP_LGE, 2533 JIT_OP_LGE_UN, 2534 JIT_OP_FGE, 2535 JIT_OP_DGE, 2536 JIT_OP_NFGE, 2537 jit_intrinsic(jit_int_ge, descr_i_ii), 2538 jit_intrinsic(jit_uint_ge, descr_i_II), 2539 jit_intrinsic(jit_long_ge, descr_i_ll), 2540 jit_intrinsic(jit_ulong_ge, descr_i_LL), 2541 jit_intrinsic(jit_float32_ge, descr_i_ff), 2542 jit_intrinsic(jit_float64_ge, descr_i_dd), 2543 jit_intrinsic(jit_nfloat_ge, descr_i_DD) 2544 }; 2545 return apply_compare(func, &ge_descr, value1, value2, 0); 2546 } 2547 2548 /*@ 2549 * @deftypefun jit_value_t jit_insn_cmpl (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2550 * Compare two values, and return a -1, 0, or 1 result. If either 2551 * value is "not a number", then -1 is returned. 2552 * @end deftypefun 2553 @*/ 2554 jit_value_t 2555 jit_insn_cmpl(jit_function_t func, jit_value_t value1, jit_value_t value2) 2556 { 2557 static jit_opcode_descr const cmpl_descr = { 2558 JIT_OP_ICMP, 2559 JIT_OP_ICMP_UN, 2560 JIT_OP_LCMP, 2561 JIT_OP_LCMP_UN, 2562 JIT_OP_FCMPL, 2563 JIT_OP_DCMPL, 2564 JIT_OP_NFCMPL, 2565 jit_intrinsic(jit_int_cmp, descr_i_ii), 2566 jit_intrinsic(jit_uint_cmp, descr_i_II), 2567 jit_intrinsic(jit_long_cmp, descr_i_ll), 2568 jit_intrinsic(jit_ulong_cmp, descr_i_LL), 2569 jit_intrinsic(jit_float32_cmpl, descr_i_ff), 2570 jit_intrinsic(jit_float64_cmpl, descr_i_dd), 2571 jit_intrinsic(jit_nfloat_cmpl, descr_i_DD) 2572 }; 2573 return apply_compare(func, &cmpl_descr, value1, value2, 0); 2574 } 2575 2576 /*@ 2577 * @deftypefun jit_value_t jit_insn_cmpg (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2578 * Compare two values, and return a -1, 0, or 1 result. If either 2579 * value is "not a number", then 1 is returned. 2580 * @end deftypefun 2581 @*/ 2582 jit_value_t 2583 jit_insn_cmpg(jit_function_t func, jit_value_t value1, jit_value_t value2) 2584 { 2585 static jit_opcode_descr const cmpg_descr = { 2586 JIT_OP_ICMP, 2587 JIT_OP_ICMP_UN, 2588 JIT_OP_LCMP, 2589 JIT_OP_LCMP_UN, 2590 JIT_OP_FCMPG, 2591 JIT_OP_DCMPG, 2592 JIT_OP_NFCMPG, 2593 jit_intrinsic(jit_int_cmp, descr_i_ii), 2594 jit_intrinsic(jit_uint_cmp, descr_i_II), 2595 jit_intrinsic(jit_long_cmp, descr_i_ll), 2596 jit_intrinsic(jit_ulong_cmp, descr_i_LL), 2597 jit_intrinsic(jit_float32_cmpg, descr_i_ff), 2598 jit_intrinsic(jit_float64_cmpg, descr_i_dd), 2599 jit_intrinsic(jit_nfloat_cmpg, descr_i_DD) 2600 }; 2601 return apply_compare(func, &cmpg_descr, value1, value2, 0); 2602 } 2603 2604 /*@ 2605 * @deftypefun jit_value_t jit_insn_to_bool (jit_function_t @var{func}, jit_value_t @var{value1}) 2606 * Convert a value into a boolean 0 or 1 result of type @code{jit_type_int}. 2607 * @end deftypefun 2608 @*/ 2609 jit_value_t 2610 jit_insn_to_bool(jit_function_t func, jit_value_t value) 2611 { 2612 /* Ensure that we have a builder for this function */ 2613 if(!_jit_function_ensure_builder(func)) 2614 { 2615 return 0; 2616 } 2617 2618 /* If the previous instruction was a comparison, then there is 2619 nothing that we need to do to make the value boolean */ 2620 int opcode; 2621 jit_block_t block = func->builder->current_block; 2622 jit_insn_t last = _jit_block_get_last(block); 2623 if(value->is_temporary && last && last->dest == value) 2624 { 2625 opcode = last->opcode; 2626 if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV) 2627 { 2628 return value; 2629 } 2630 } 2631 2632 /* Perform a comparison to determine if the value is non-zero */ 2633 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 2634 jit_value_t zero; 2635 switch(type->kind) 2636 { 2637 default: /* Shouldn't happen */ 2638 case JIT_TYPE_INT: 2639 case JIT_TYPE_UINT: 2640 zero = jit_value_create_nint_constant(func, jit_type_int, 0); 2641 break; 2642 case JIT_TYPE_LONG: 2643 case JIT_TYPE_ULONG: 2644 zero = jit_value_create_long_constant(func, jit_type_long, 0); 2645 break; 2646 case JIT_TYPE_FLOAT32: 2647 zero = jit_value_create_float32_constant(func, jit_type_float32, 2648 (jit_float32) 0.0); 2649 break; 2650 case JIT_TYPE_FLOAT64: 2651 zero = jit_value_create_float64_constant(func, jit_type_float64, 2652 (jit_float64) 0.0); 2653 break; 2654 case JIT_TYPE_NFLOAT: 2655 zero = jit_value_create_nfloat_constant(func, jit_type_nfloat, 2656 (jit_nfloat) 0.0); 2657 break; 2658 } 2659 if(!zero) 2660 { 2661 return 0; 2662 } 2663 return jit_insn_ne(func, value, zero); 2664 } 2665 2666 /*@ 2667 * @deftypefun jit_value_t jit_insn_to_not_bool (jit_function_t @var{func}, jit_value_t @var{value1}) 2668 * Convert a value into a boolean 1 or 0 result of type @code{jit_type_int} 2669 * (i.e. the inverse of @code{jit_insn_to_bool}). 2670 * @end deftypefun 2671 @*/ 2672 jit_value_t 2673 jit_insn_to_not_bool(jit_function_t func, jit_value_t value) 2674 { 2675 /* Ensure that we have a builder for this function */ 2676 if(!_jit_function_ensure_builder(func)) 2677 { 2678 return 0; 2679 } 2680 2681 /* If the previous instruction was a comparison, then all 2682 we have to do is invert the comparison opcode */ 2683 int opcode; 2684 jit_block_t block = func->builder->current_block; 2685 jit_insn_t last = _jit_block_get_last(block); 2686 if(value->is_temporary && last && last->dest == value) 2687 { 2688 opcode = last->opcode; 2689 if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV) 2690 { 2691 switch(opcode) 2692 { 2693 case JIT_OP_IEQ: opcode = JIT_OP_INE; break; 2694 case JIT_OP_INE: opcode = JIT_OP_IEQ; break; 2695 case JIT_OP_ILT: opcode = JIT_OP_IGE; break; 2696 case JIT_OP_ILT_UN: opcode = JIT_OP_IGE_UN; break; 2697 case JIT_OP_ILE: opcode = JIT_OP_IGT; break; 2698 case JIT_OP_ILE_UN: opcode = JIT_OP_IGT_UN; break; 2699 case JIT_OP_IGT: opcode = JIT_OP_ILE; break; 2700 case JIT_OP_IGT_UN: opcode = JIT_OP_ILE_UN; break; 2701 case JIT_OP_IGE: opcode = JIT_OP_ILT; break; 2702 case JIT_OP_IGE_UN: opcode = JIT_OP_ILT_UN; break; 2703 case JIT_OP_LEQ: opcode = JIT_OP_LNE; break; 2704 case JIT_OP_LNE: opcode = JIT_OP_LEQ; break; 2705 case JIT_OP_LLT: opcode = JIT_OP_LGE; break; 2706 case JIT_OP_LLT_UN: opcode = JIT_OP_LGE_UN; break; 2707 case JIT_OP_LLE: opcode = JIT_OP_LGT; break; 2708 case JIT_OP_LLE_UN: opcode = JIT_OP_LGT_UN; break; 2709 case JIT_OP_LGT: opcode = JIT_OP_LLE; break; 2710 case JIT_OP_LGT_UN: opcode = JIT_OP_LLE_UN; break; 2711 case JIT_OP_LGE: opcode = JIT_OP_LLT; break; 2712 case JIT_OP_LGE_UN: opcode = JIT_OP_LLT_UN; break; 2713 case JIT_OP_FEQ: opcode = JIT_OP_FNE; break; 2714 case JIT_OP_FNE: opcode = JIT_OP_FEQ; break; 2715 case JIT_OP_FLT: opcode = JIT_OP_FGE_INV; break; 2716 case JIT_OP_FLE: opcode = JIT_OP_FGT_INV; break; 2717 case JIT_OP_FGT: opcode = JIT_OP_FLE_INV; break; 2718 case JIT_OP_FGE: opcode = JIT_OP_FLT_INV; break; 2719 case JIT_OP_FLT_INV: opcode = JIT_OP_FGE; break; 2720 case JIT_OP_FLE_INV: opcode = JIT_OP_FGT; break; 2721 case JIT_OP_FGT_INV: opcode = JIT_OP_FLE; break; 2722 case JIT_OP_FGE_INV: opcode = JIT_OP_FLT; break; 2723 case JIT_OP_DEQ: opcode = JIT_OP_DNE; break; 2724 case JIT_OP_DNE: opcode = JIT_OP_DEQ; break; 2725 case JIT_OP_DLT: opcode = JIT_OP_DGE_INV; break; 2726 case JIT_OP_DLE: opcode = JIT_OP_DGT_INV; break; 2727 case JIT_OP_DGT: opcode = JIT_OP_DLE_INV; break; 2728 case JIT_OP_DGE: opcode = JIT_OP_DLT_INV; break; 2729 case JIT_OP_DLT_INV: opcode = JIT_OP_DGE; break; 2730 case JIT_OP_DLE_INV: opcode = JIT_OP_DGT; break; 2731 case JIT_OP_DGT_INV: opcode = JIT_OP_DLE; break; 2732 case JIT_OP_DGE_INV: opcode = JIT_OP_DLT; break; 2733 case JIT_OP_NFEQ: opcode = JIT_OP_NFNE; break; 2734 case JIT_OP_NFNE: opcode = JIT_OP_NFEQ; break; 2735 case JIT_OP_NFLT: opcode = JIT_OP_NFGE_INV; break; 2736 case JIT_OP_NFLE: opcode = JIT_OP_NFGT_INV; break; 2737 case JIT_OP_NFGT: opcode = JIT_OP_NFLE_INV; break; 2738 case JIT_OP_NFGE: opcode = JIT_OP_NFLT_INV; break; 2739 case JIT_OP_NFLT_INV: opcode = JIT_OP_NFGE; break; 2740 case JIT_OP_NFLE_INV: opcode = JIT_OP_NFGT; break; 2741 case JIT_OP_NFGT_INV: opcode = JIT_OP_NFLE; break; 2742 case JIT_OP_NFGE_INV: opcode = JIT_OP_NFLT; break; 2743 } 2744 last->opcode = (short) opcode; 2745 return value; 2746 } 2747 } 2748 2749 /* Perform a comparison to determine if the value is zero */ 2750 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 2751 jit_value_t zero; 2752 switch(type->kind) 2753 { 2754 default: /* Shouldn't happen */ 2755 case JIT_TYPE_INT: 2756 case JIT_TYPE_UINT: 2757 zero = jit_value_create_nint_constant(func, jit_type_int, 0); 2758 break; 2759 case JIT_TYPE_LONG: 2760 case JIT_TYPE_ULONG: 2761 zero = jit_value_create_long_constant(func, jit_type_long, 0); 2762 break; 2763 case JIT_TYPE_FLOAT32: 2764 zero = jit_value_create_float32_constant(func, jit_type_float32, 2765 (jit_float32) 0.0); 2766 break; 2767 case JIT_TYPE_FLOAT64: 2768 zero = jit_value_create_float64_constant(func, jit_type_float64, 2769 (jit_float64) 0.0); 2770 break; 2771 case JIT_TYPE_NFLOAT: 2772 zero = jit_value_create_nfloat_constant(func, jit_type_nfloat, 2773 (jit_nfloat) 0.0); 2774 break; 2775 } 2776 if(!zero) 2777 { 2778 return 0; 2779 } 2780 return jit_insn_eq(func, value, zero); 2781 } 2782 2783 /*@ 2784 * @deftypefun jit_value_t jit_insn_acos (jit_function_t @var{func}, jit_value_t @var{value1}) 2785 * @deftypefunx jit_value_t jit_insn_asin (jit_function_t @var{func}, jit_value_t @var{value1}) 2786 * @deftypefunx jit_value_t jit_insn_atan (jit_function_t @var{func}, jit_value_t @var{value1}) 2787 * @deftypefunx jit_value_t jit_insn_atan2 (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2788 * @deftypefunx jit_value_t jit_insn_cos (jit_function_t @var{func}, jit_value_t @var{value1}) 2789 * @deftypefunx jit_value_t jit_insn_cosh (jit_function_t @var{func}, jit_value_t @var{value1}) 2790 * @deftypefunx jit_value_t jit_insn_exp (jit_function_t @var{func}, jit_value_t @var{value1}) 2791 * @deftypefunx jit_value_t jit_insn_log (jit_function_t @var{func}, jit_value_t @var{value1}) 2792 * @deftypefunx jit_value_t jit_insn_log10 (jit_function_t @var{func}, jit_value_t @var{value1}) 2793 * @deftypefunx jit_value_t jit_insn_pow (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 2794 * @deftypefunx jit_value_t jit_insn_sin (jit_function_t @var{func}, jit_value_t @var{value1}) 2795 * @deftypefunx jit_value_t jit_insn_sinh (jit_function_t @var{func}, jit_value_t @var{value1}) 2796 * @deftypefunx jit_value_t jit_insn_sqrt (jit_function_t @var{func}, jit_value_t @var{value1}) 2797 * @deftypefunx jit_value_t jit_insn_tan (jit_function_t @var{func}, jit_value_t @var{value1}) 2798 * @deftypefunx jit_value_t jit_insn_tanh (jit_function_t @var{func}, jit_value_t @var{value1}) 2799 * Apply a mathematical function to floating-point arguments. 2800 * @end deftypefun 2801 @*/ 2802 jit_value_t 2803 jit_insn_acos(jit_function_t func, jit_value_t value) 2804 { 2805 static jit_opcode_descr const acos_descr = { 2806 0, 0, 0, 0, 2807 JIT_OP_FACOS, 2808 JIT_OP_DACOS, 2809 JIT_OP_NFACOS, 2810 jit_no_intrinsic, 2811 jit_no_intrinsic, 2812 jit_no_intrinsic, 2813 jit_no_intrinsic, 2814 jit_intrinsic(jit_float32_acos, descr_f_f), 2815 jit_intrinsic(jit_float64_acos, descr_d_d), 2816 jit_intrinsic(jit_nfloat_acos, descr_D_D) 2817 }; 2818 return apply_unary_arith(func, &acos_descr, value, 0, 1, 0); 2819 } 2820 2821 jit_value_t 2822 jit_insn_asin(jit_function_t func, jit_value_t value) 2823 { 2824 static jit_opcode_descr const asin_descr = { 2825 0, 0, 0, 0, 2826 JIT_OP_FASIN, 2827 JIT_OP_DASIN, 2828 JIT_OP_NFASIN, 2829 jit_no_intrinsic, 2830 jit_no_intrinsic, 2831 jit_no_intrinsic, 2832 jit_no_intrinsic, 2833 jit_intrinsic(jit_float32_asin, descr_f_f), 2834 jit_intrinsic(jit_float64_asin, descr_d_d), 2835 jit_intrinsic(jit_nfloat_asin, descr_D_D) 2836 }; 2837 return apply_unary_arith(func, &asin_descr, value, 0, 1, 0); 2838 } 2839 2840 jit_value_t 2841 jit_insn_atan(jit_function_t func, jit_value_t value) 2842 { 2843 static jit_opcode_descr const atan_descr = { 2844 0, 0, 0, 0, 2845 JIT_OP_FATAN, 2846 JIT_OP_DATAN, 2847 JIT_OP_NFATAN, 2848 jit_no_intrinsic, 2849 jit_no_intrinsic, 2850 jit_no_intrinsic, 2851 jit_no_intrinsic, 2852 jit_intrinsic(jit_float32_atan, descr_f_f), 2853 jit_intrinsic(jit_float64_atan, descr_d_d), 2854 jit_intrinsic(jit_nfloat_atan, descr_D_D) 2855 }; 2856 return apply_unary_arith(func, &atan_descr, value, 0, 1, 0); 2857 } 2858 2859 jit_value_t 2860 jit_insn_atan2(jit_function_t func, jit_value_t value1, jit_value_t value2) 2861 { 2862 static jit_opcode_descr const atan2_descr = { 2863 0, 0, 0, 0, 2864 JIT_OP_FATAN2, 2865 JIT_OP_DATAN2, 2866 JIT_OP_NFATAN2, 2867 jit_no_intrinsic, 2868 jit_no_intrinsic, 2869 jit_no_intrinsic, 2870 jit_no_intrinsic, 2871 jit_intrinsic(jit_float32_atan2, descr_f_ff), 2872 jit_intrinsic(jit_float64_atan2, descr_d_dd), 2873 jit_intrinsic(jit_nfloat_atan2, descr_D_DD) 2874 }; 2875 return apply_arith(func, &atan2_descr, value1, value2, 0, 1, 0); 2876 } 2877 2878 /*@ 2879 * @deftypefun jit_value_t jit_insn_ceil (jit_function_t @var{func}, jit_value_t @var{value1}) 2880 * Round @var{value1} up towads positive infinity. 2881 * @end deftypefun 2882 @*/ 2883 jit_value_t 2884 jit_insn_ceil(jit_function_t func, jit_value_t value) 2885 { 2886 static jit_opcode_descr const ceil_descr = { 2887 0, 0, 0, 0, 2888 JIT_OP_FCEIL, 2889 JIT_OP_DCEIL, 2890 JIT_OP_NFCEIL, 2891 jit_no_intrinsic, 2892 jit_no_intrinsic, 2893 jit_no_intrinsic, 2894 jit_no_intrinsic, 2895 jit_intrinsic(jit_float32_ceil, descr_f_f), 2896 jit_intrinsic(jit_float64_ceil, descr_d_d), 2897 jit_intrinsic(jit_nfloat_ceil, descr_D_D) 2898 }; 2899 return apply_unary_arith(func, &ceil_descr, value, 0, 1, 0); 2900 } 2901 2902 jit_value_t 2903 jit_insn_cos(jit_function_t func, jit_value_t value) 2904 { 2905 static jit_opcode_descr const cos_descr = { 2906 0, 0, 0, 0, 2907 JIT_OP_FCOS, 2908 JIT_OP_DCOS, 2909 JIT_OP_NFCOS, 2910 jit_no_intrinsic, 2911 jit_no_intrinsic, 2912 jit_no_intrinsic, 2913 jit_no_intrinsic, 2914 jit_intrinsic(jit_float32_cos, descr_f_f), 2915 jit_intrinsic(jit_float64_cos, descr_d_d), 2916 jit_intrinsic(jit_nfloat_cos, descr_D_D) 2917 }; 2918 return apply_unary_arith(func, &cos_descr, value, 0, 1, 0); 2919 } 2920 2921 jit_value_t 2922 jit_insn_cosh(jit_function_t func, jit_value_t value) 2923 { 2924 static jit_opcode_descr const cosh_descr = { 2925 0, 0, 0, 0, 2926 JIT_OP_FCOSH, 2927 JIT_OP_DCOSH, 2928 JIT_OP_NFCOSH, 2929 jit_no_intrinsic, 2930 jit_no_intrinsic, 2931 jit_no_intrinsic, 2932 jit_no_intrinsic, 2933 jit_intrinsic(jit_float32_cosh, descr_f_f), 2934 jit_intrinsic(jit_float64_cosh, descr_d_d), 2935 jit_intrinsic(jit_nfloat_cosh, descr_D_D) 2936 }; 2937 return apply_unary_arith(func, &cosh_descr, value, 0, 1, 0); 2938 } 2939 2940 jit_value_t 2941 jit_insn_exp(jit_function_t func, jit_value_t value) 2942 { 2943 static jit_opcode_descr const exp_descr = { 2944 0, 0, 0, 0, 2945 JIT_OP_FEXP, 2946 JIT_OP_DEXP, 2947 JIT_OP_NFEXP, 2948 jit_no_intrinsic, 2949 jit_no_intrinsic, 2950 jit_no_intrinsic, 2951 jit_no_intrinsic, 2952 jit_intrinsic(jit_float32_exp, descr_f_f), 2953 jit_intrinsic(jit_float64_exp, descr_d_d), 2954 jit_intrinsic(jit_nfloat_exp, descr_D_D) 2955 }; 2956 return apply_unary_arith(func, &exp_descr, value, 0, 1, 0); 2957 } 2958 2959 /*@ 2960 * @deftypefun jit_value_t jit_insn_floor (jit_function_t @var{func}, jit_value_t @var{value1}) 2961 * Round @var{value1} down towards negative infinity. 2962 * @end deftypefun 2963 @*/ 2964 jit_value_t 2965 jit_insn_floor(jit_function_t func, jit_value_t value) 2966 { 2967 static jit_opcode_descr const floor_descr = { 2968 0, 0, 0, 0, 2969 JIT_OP_FFLOOR, 2970 JIT_OP_DFLOOR, 2971 JIT_OP_NFFLOOR, 2972 jit_no_intrinsic, 2973 jit_no_intrinsic, 2974 jit_no_intrinsic, 2975 jit_no_intrinsic, 2976 jit_intrinsic(jit_float32_floor, descr_f_f), 2977 jit_intrinsic(jit_float64_floor, descr_d_d), 2978 jit_intrinsic(jit_nfloat_floor, descr_D_D) 2979 }; 2980 return apply_unary_arith(func, &floor_descr, value, 0, 1, 0); 2981 } 2982 2983 jit_value_t 2984 jit_insn_log(jit_function_t func, jit_value_t value) 2985 { 2986 static jit_opcode_descr const log_descr = { 2987 0, 0, 0, 0, 2988 JIT_OP_FLOG, 2989 JIT_OP_DLOG, 2990 JIT_OP_NFLOG, 2991 jit_no_intrinsic, 2992 jit_no_intrinsic, 2993 jit_no_intrinsic, 2994 jit_no_intrinsic, 2995 jit_intrinsic(jit_float32_log, descr_f_f), 2996 jit_intrinsic(jit_float64_log, descr_d_d), 2997 jit_intrinsic(jit_nfloat_log, descr_D_D) 2998 }; 2999 return apply_unary_arith(func, &log_descr, value, 0, 1, 0); 3000 } 3001 3002 jit_value_t 3003 jit_insn_log10(jit_function_t func, jit_value_t value) 3004 { 3005 static jit_opcode_descr const log10_descr = { 3006 0, 0, 0, 0, 3007 JIT_OP_FLOG10, 3008 JIT_OP_DLOG10, 3009 JIT_OP_NFLOG10, 3010 jit_no_intrinsic, 3011 jit_no_intrinsic, 3012 jit_no_intrinsic, 3013 jit_no_intrinsic, 3014 jit_intrinsic(jit_float32_log10, descr_f_f), 3015 jit_intrinsic(jit_float64_log10, descr_d_d), 3016 jit_intrinsic(jit_nfloat_log10, descr_D_D) 3017 }; 3018 return apply_unary_arith(func, &log10_descr, value, 0, 1, 0); 3019 } 3020 3021 jit_value_t 3022 jit_insn_pow(jit_function_t func, jit_value_t value1, jit_value_t value2) 3023 { 3024 static jit_opcode_descr const pow_descr = { 3025 0, 0, 0, 0, 3026 JIT_OP_FPOW, 3027 JIT_OP_DPOW, 3028 JIT_OP_NFPOW, 3029 jit_no_intrinsic, 3030 jit_no_intrinsic, 3031 jit_no_intrinsic, 3032 jit_no_intrinsic, 3033 jit_intrinsic(jit_float32_pow, descr_f_ff), 3034 jit_intrinsic(jit_float64_pow, descr_d_dd), 3035 jit_intrinsic(jit_nfloat_pow, descr_D_DD) 3036 }; 3037 return apply_arith(func, &pow_descr, value1, value2, 0, 1, 0); 3038 } 3039 3040 /*@ 3041 * @deftypefun jit_value_t jit_insn_rint (jit_function_t @var{func}, jit_value_t @var{value1}) 3042 * Round @var{value1} to the nearest integer. Half-way cases are rounded to the even number. 3043 * @end deftypefun 3044 @*/ 3045 jit_value_t 3046 jit_insn_rint(jit_function_t func, jit_value_t value) 3047 { 3048 static jit_opcode_descr const rint_descr = { 3049 0, 0, 0, 0, 3050 JIT_OP_FRINT, 3051 JIT_OP_DRINT, 3052 JIT_OP_NFRINT, 3053 jit_no_intrinsic, 3054 jit_no_intrinsic, 3055 jit_no_intrinsic, 3056 jit_no_intrinsic, 3057 jit_intrinsic(jit_float32_rint, descr_f_f), 3058 jit_intrinsic(jit_float64_rint, descr_d_d), 3059 jit_intrinsic(jit_nfloat_rint, descr_D_D) 3060 }; 3061 return apply_unary_arith(func, &rint_descr, value, 0, 1, 0); 3062 } 3063 3064 /*@ 3065 * @deftypefun jit_value_t jit_insn_round (jit_function_t @var{func}, jit_value_t @var{value1}) 3066 * Round @var{value1} to the nearest integer. Half-way cases are rounded away from zero. 3067 * @end deftypefun 3068 @*/ 3069 jit_value_t 3070 jit_insn_round(jit_function_t func, jit_value_t value) 3071 { 3072 static jit_opcode_descr const round_descr = { 3073 0, 0, 0, 0, 3074 JIT_OP_FROUND, 3075 JIT_OP_DROUND, 3076 JIT_OP_NFROUND, 3077 jit_no_intrinsic, 3078 jit_no_intrinsic, 3079 jit_no_intrinsic, 3080 jit_no_intrinsic, 3081 jit_intrinsic(jit_float32_round, descr_f_f), 3082 jit_intrinsic(jit_float64_round, descr_d_d), 3083 jit_intrinsic(jit_nfloat_round, descr_D_D) 3084 }; 3085 return apply_unary_arith(func, &round_descr, value, 0, 1, 0); 3086 } 3087 3088 jit_value_t 3089 jit_insn_sin(jit_function_t func, jit_value_t value) 3090 { 3091 static jit_opcode_descr const sin_descr = { 3092 0, 0, 0, 0, 3093 JIT_OP_FSIN, 3094 JIT_OP_DSIN, 3095 JIT_OP_NFSIN, 3096 jit_no_intrinsic, 3097 jit_no_intrinsic, 3098 jit_no_intrinsic, 3099 jit_no_intrinsic, 3100 jit_intrinsic(jit_float32_sin, descr_f_f), 3101 jit_intrinsic(jit_float64_sin, descr_d_d), 3102 jit_intrinsic(jit_nfloat_sin, descr_D_D) 3103 }; 3104 return apply_unary_arith(func, &sin_descr, value, 0, 1, 0); 3105 } 3106 3107 jit_value_t 3108 jit_insn_sinh(jit_function_t func, jit_value_t value) 3109 { 3110 static jit_opcode_descr const sinh_descr = { 3111 0, 0, 0, 0, 3112 JIT_OP_FSINH, 3113 JIT_OP_DSINH, 3114 JIT_OP_NFSINH, 3115 jit_no_intrinsic, 3116 jit_no_intrinsic, 3117 jit_no_intrinsic, 3118 jit_no_intrinsic, 3119 jit_intrinsic(jit_float32_sinh, descr_f_f), 3120 jit_intrinsic(jit_float64_sinh, descr_d_d), 3121 jit_intrinsic(jit_nfloat_sinh, descr_D_D) 3122 }; 3123 return apply_unary_arith(func, &sinh_descr, value, 0, 1, 0); 3124 } 3125 3126 jit_value_t 3127 jit_insn_sqrt(jit_function_t func, jit_value_t value) 3128 { 3129 static jit_opcode_descr const sqrt_descr = { 3130 0, 0, 0, 0, 3131 JIT_OP_FSQRT, 3132 JIT_OP_DSQRT, 3133 JIT_OP_NFSQRT, 3134 jit_no_intrinsic, 3135 jit_no_intrinsic, 3136 jit_no_intrinsic, 3137 jit_no_intrinsic, 3138 jit_intrinsic(jit_float32_sqrt, descr_f_f), 3139 jit_intrinsic(jit_float64_sqrt, descr_d_d), 3140 jit_intrinsic(jit_nfloat_sqrt, descr_D_D) 3141 }; 3142 return apply_unary_arith(func, &sqrt_descr, value, 0, 1, 0); 3143 } 3144 3145 jit_value_t 3146 jit_insn_tan(jit_function_t func, jit_value_t value) 3147 { 3148 static jit_opcode_descr const tan_descr = { 3149 0, 0, 0, 0, 3150 JIT_OP_FTAN, 3151 JIT_OP_DTAN, 3152 JIT_OP_NFTAN, 3153 jit_no_intrinsic, 3154 jit_no_intrinsic, 3155 jit_no_intrinsic, 3156 jit_no_intrinsic, 3157 jit_intrinsic(jit_float32_tan, descr_f_f), 3158 jit_intrinsic(jit_float64_tan, descr_d_d), 3159 jit_intrinsic(jit_nfloat_tan, descr_D_D) 3160 }; 3161 return apply_unary_arith(func, &tan_descr, value, 0, 1, 0); 3162 } 3163 3164 jit_value_t 3165 jit_insn_tanh(jit_function_t func, jit_value_t value) 3166 { 3167 static jit_opcode_descr const tanh_descr = { 3168 0, 0, 0, 0, 3169 JIT_OP_FTANH, 3170 JIT_OP_DTANH, 3171 JIT_OP_NFTANH, 3172 jit_no_intrinsic, 3173 jit_no_intrinsic, 3174 jit_no_intrinsic, 3175 jit_no_intrinsic, 3176 jit_intrinsic(jit_float32_tanh, descr_f_f), 3177 jit_intrinsic(jit_float64_tanh, descr_d_d), 3178 jit_intrinsic(jit_nfloat_tanh, descr_D_D) 3179 }; 3180 return apply_unary_arith(func, &tanh_descr, value, 0, 1, 0); 3181 } 3182 3183 /*@ 3184 * @deftypefun jit_value_t jit_insn_trunc (jit_function_t @var{func}, jit_value_t @var{value1}) 3185 * Round @var{value1} towards zero. 3186 * @end deftypefun 3187 @*/ 3188 jit_value_t 3189 jit_insn_trunc(jit_function_t func, jit_value_t value) 3190 { 3191 static jit_opcode_descr const trunc_descr = { 3192 0, 0, 0, 0, 3193 JIT_OP_FTRUNC, 3194 JIT_OP_DTRUNC, 3195 JIT_OP_NFTRUNC, 3196 jit_no_intrinsic, 3197 jit_no_intrinsic, 3198 jit_no_intrinsic, 3199 jit_no_intrinsic, 3200 jit_intrinsic(jit_float32_trunc, descr_f_f), 3201 jit_intrinsic(jit_float64_trunc, descr_d_d), 3202 jit_intrinsic(jit_nfloat_trunc, descr_D_D) 3203 }; 3204 return apply_unary_arith(func, &trunc_descr, value, 0, 1, 0); 3205 } 3206 3207 /*@ 3208 * @deftypefun jit_value_t jit_insn_is_nan (jit_function_t @var{func}, jit_value_t @var{value1}) 3209 * @deftypefunx jit_value_t jit_insn_is_finite (jit_function_t @var{func}, jit_value_t @var{value1}) 3210 * @deftypefunx jit_value_t jit_insn_is_inf (jit_function_t @var{func}, jit_value_t @var{value1}) 3211 * Test a floating point value for not a number, finite, or infinity. 3212 * @end deftypefun 3213 @*/ 3214 jit_value_t 3215 jit_insn_is_nan(jit_function_t func, jit_value_t value) 3216 { 3217 static jit_opcode_descr const is_nan_descr = { 3218 0, 0, 0, 0, 3219 JIT_OP_IS_FNAN, 3220 JIT_OP_IS_DNAN, 3221 JIT_OP_IS_NFNAN, 3222 jit_no_intrinsic, 3223 jit_no_intrinsic, 3224 jit_no_intrinsic, 3225 jit_no_intrinsic, 3226 jit_intrinsic(jit_float32_is_nan, descr_i_f), 3227 jit_intrinsic(jit_float64_is_nan, descr_i_d), 3228 jit_intrinsic(jit_nfloat_is_nan, descr_i_D) 3229 }; 3230 return test_float_value(func, &is_nan_descr, value); 3231 } 3232 3233 jit_value_t 3234 jit_insn_is_finite(jit_function_t func, jit_value_t value) 3235 { 3236 static jit_opcode_descr const is_finite_descr = { 3237 0, 0, 0, 0, 3238 JIT_OP_IS_FFINITE, 3239 JIT_OP_IS_DFINITE, 3240 JIT_OP_IS_NFFINITE, 3241 jit_no_intrinsic, 3242 jit_no_intrinsic, 3243 jit_no_intrinsic, 3244 jit_no_intrinsic, 3245 jit_intrinsic(jit_float32_is_finite, descr_i_f), 3246 jit_intrinsic(jit_float64_is_finite, descr_i_d), 3247 jit_intrinsic(jit_nfloat_is_finite, descr_i_D) 3248 }; 3249 return test_float_value(func, &is_finite_descr, value); 3250 } 3251 3252 jit_value_t 3253 jit_insn_is_inf(jit_function_t func, jit_value_t value) 3254 { 3255 static jit_opcode_descr const is_inf_descr = { 3256 0, 0, 0, 0, 3257 JIT_OP_IS_FINF, 3258 JIT_OP_IS_DINF, 3259 JIT_OP_IS_NFINF, 3260 jit_no_intrinsic, 3261 jit_no_intrinsic, 3262 jit_no_intrinsic, 3263 jit_no_intrinsic, 3264 jit_intrinsic(jit_float32_is_inf, descr_i_f), 3265 jit_intrinsic(jit_float64_is_inf, descr_i_d), 3266 jit_intrinsic(jit_nfloat_is_inf, descr_i_D) 3267 }; 3268 return test_float_value(func, &is_inf_descr, value); 3269 } 3270 3271 /*@ 3272 * @deftypefun jit_value_t jit_insn_abs (jit_function_t @var{func}, jit_value_t @var{value1}) 3273 * @deftypefunx jit_value_t jit_insn_min (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 3274 * @deftypefunx jit_value_t jit_insn_max (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2}) 3275 * @deftypefunx jit_value_t jit_insn_sign (jit_function_t @var{func}, jit_value_t @var{value1}) 3276 * Calculate the absolute value, minimum, maximum, or sign of the 3277 * specified values. 3278 * @end deftypefun 3279 @*/ 3280 jit_value_t 3281 jit_insn_abs(jit_function_t func, jit_value_t value) 3282 { 3283 int oper; 3284 void *intrinsic; 3285 const char *name; 3286 const jit_intrinsic_descr_t *descr; 3287 3288 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 3289 switch (type->kind) 3290 { 3291 case JIT_TYPE_INT: 3292 oper = JIT_OP_IABS; 3293 intrinsic = (void *) jit_int_abs; 3294 name = "jit_int_abs"; 3295 descr = &descr_i_i; 3296 break; 3297 case JIT_TYPE_UINT: 3298 oper = 0; 3299 intrinsic = (void *) 0; 3300 name = 0; 3301 descr = 0; 3302 break; 3303 case JIT_TYPE_LONG: 3304 oper = JIT_OP_LABS; 3305 intrinsic = (void *) jit_long_abs; 3306 name = "jit_long_abs"; 3307 descr = &descr_l_l; 3308 break; 3309 case JIT_TYPE_ULONG: 3310 oper = 0; 3311 intrinsic = (void *) 0; 3312 name = 0; 3313 descr = 0; 3314 break; 3315 case JIT_TYPE_FLOAT32: 3316 oper = JIT_OP_FABS; 3317 intrinsic = (void *) jit_float32_abs; 3318 name = "jit_float32_abs"; 3319 descr = &descr_f_f; 3320 break; 3321 case JIT_TYPE_FLOAT64: 3322 oper = JIT_OP_DABS; 3323 intrinsic = (void *) jit_float64_abs; 3324 name = "jit_float64_abs"; 3325 descr = &descr_d_d; 3326 break; 3327 case JIT_TYPE_NFLOAT: 3328 oper = JIT_OP_NFABS; 3329 intrinsic = (void *) jit_nfloat_abs; 3330 name = "jit_nfloat_abs"; 3331 descr = &descr_D_D; 3332 break; 3333 default: 3334 return 0; 3335 } 3336 3337 value = jit_insn_convert(func, value, type, 0); 3338 if(!value) 3339 { 3340 return 0; 3341 } 3342 if(!oper) 3343 { 3344 /* Absolute value of an unsigned value */ 3345 return value; 3346 } 3347 if(jit_value_is_constant(value)) 3348 { 3349 jit_value_t result = _jit_opcode_apply_unary(func, oper, value, type); 3350 if(result) 3351 { 3352 return result; 3353 } 3354 } 3355 3356 if(!_jit_opcode_is_supported(oper)) 3357 { 3358 return jit_insn_call_intrinsic(func, name, intrinsic, descr, value, 0); 3359 } 3360 return apply_unary(func, oper, value, type); 3361 } 3362 3363 jit_value_t 3364 jit_insn_min(jit_function_t func, jit_value_t value1, jit_value_t value2) 3365 { 3366 static jit_opcode_descr const min_descr = { 3367 JIT_OP_IMIN, 3368 JIT_OP_IMIN_UN, 3369 JIT_OP_LMIN, 3370 JIT_OP_LMIN_UN, 3371 JIT_OP_FMIN, 3372 JIT_OP_DMIN, 3373 JIT_OP_NFMIN, 3374 jit_intrinsic(jit_int_min, descr_i_ii), 3375 jit_intrinsic(jit_uint_min, descr_I_II), 3376 jit_intrinsic(jit_long_min, descr_l_ll), 3377 jit_intrinsic(jit_ulong_min, descr_L_LL), 3378 jit_intrinsic(jit_float32_min, descr_f_ff), 3379 jit_intrinsic(jit_float64_min, descr_d_dd), 3380 jit_intrinsic(jit_nfloat_min, descr_D_DD) 3381 }; 3382 return apply_arith(func, &min_descr, value1, value2, 0, 0, 0); 3383 } 3384 3385 jit_value_t 3386 jit_insn_max(jit_function_t func, jit_value_t value1, jit_value_t value2) 3387 { 3388 static jit_opcode_descr const max_descr = { 3389 JIT_OP_IMAX, 3390 JIT_OP_IMAX_UN, 3391 JIT_OP_LMAX, 3392 JIT_OP_LMAX_UN, 3393 JIT_OP_FMAX, 3394 JIT_OP_DMAX, 3395 JIT_OP_NFMAX, 3396 jit_intrinsic(jit_int_max, descr_i_ii), 3397 jit_intrinsic(jit_uint_max, descr_I_II), 3398 jit_intrinsic(jit_long_max, descr_l_ll), 3399 jit_intrinsic(jit_ulong_max, descr_L_LL), 3400 jit_intrinsic(jit_float32_max, descr_f_ff), 3401 jit_intrinsic(jit_float64_max, descr_d_dd), 3402 jit_intrinsic(jit_nfloat_max, descr_D_DD) 3403 }; 3404 return apply_arith(func, &max_descr, value1, value2, 0, 0, 0); 3405 } 3406 3407 jit_value_t 3408 jit_insn_sign(jit_function_t func, jit_value_t value) 3409 { 3410 int oper; 3411 void *intrinsic; 3412 const char *name; 3413 const jit_intrinsic_descr_t *descr; 3414 jit_value_t zero; 3415 3416 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 3417 switch (type->kind) 3418 { 3419 case JIT_TYPE_INT: 3420 oper = JIT_OP_ISIGN; 3421 intrinsic = (void *) jit_int_sign; 3422 name = "jit_int_sign"; 3423 descr = &descr_i_i; 3424 break; 3425 case JIT_TYPE_UINT: 3426 zero = jit_value_create_nint_constant(func, jit_type_uint, 0); 3427 if(!zero) 3428 { 3429 return 0; 3430 } 3431 return jit_insn_ne(func, value, zero); 3432 case JIT_TYPE_LONG: 3433 oper = JIT_OP_LSIGN; 3434 intrinsic = (void *) jit_long_sign; 3435 name = "jit_long_sign"; 3436 descr = &descr_i_l; 3437 break; 3438 case JIT_TYPE_ULONG: 3439 zero = jit_value_create_long_constant(func, jit_type_ulong, 0); 3440 if(!zero) 3441 { 3442 return 0; 3443 } 3444 return jit_insn_ne(func, value, zero); 3445 case JIT_TYPE_FLOAT32: 3446 oper = JIT_OP_FSIGN; 3447 intrinsic = (void *) jit_float32_sign; 3448 name = "jit_float32_sign"; 3449 descr = &descr_i_f; 3450 break; 3451 case JIT_TYPE_FLOAT64: 3452 oper = JIT_OP_DSIGN; 3453 intrinsic = (void *) jit_float64_sign; 3454 name = "jit_float64_sign"; 3455 descr = &descr_i_d; 3456 break; 3457 case JIT_TYPE_NFLOAT: 3458 oper = JIT_OP_NFSIGN; 3459 intrinsic = (void *) jit_nfloat_sign; 3460 name = "jit_nfloat_sign"; 3461 descr = &descr_i_D; 3462 break; 3463 default: 3464 return 0; 3465 } 3466 3467 value = jit_insn_convert(func, value, type, 0); 3468 if(!value) 3469 { 3470 return 0; 3471 } 3472 if(jit_value_is_constant(value)) 3473 { 3474 jit_value_t result = _jit_opcode_apply_unary(func, oper, value, type); 3475 if(result) 3476 { 3477 return result; 3478 } 3479 } 3480 3481 if(!_jit_opcode_is_supported(oper)) 3482 { 3483 return jit_insn_call_intrinsic(func, name, intrinsic, descr, value, 0); 3484 } 3485 return apply_unary(func, oper, value, jit_type_int); 3486 } 3487 3488 /*@ 3489 * @deftypefun int jit_insn_branch (jit_function_t @var{func}, jit_label_t *@var{label}) 3490 * Terminate the current block by branching unconditionally 3491 * to a specific label. Returns zero if out of memory. 3492 * @end deftypefun 3493 @*/ 3494 int 3495 jit_insn_branch(jit_function_t func, jit_label_t *label) 3496 { 3497 /* Ensure that we have a function builder */ 3498 if(!_jit_function_ensure_builder(func)) 3499 { 3500 return 0; 3501 } 3502 3503 /* Flush any stack pops that were deferred previously */ 3504 if(!jit_insn_flush_defer_pop(func, 0)) 3505 { 3506 return 0; 3507 } 3508 3509 /* Allocate a new label identifier, if necessary */ 3510 if(*label == jit_label_undefined) 3511 { 3512 *label = func->builder->next_label++; 3513 } 3514 3515 /* Add a new branch instruction */ 3516 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 3517 if(!insn) 3518 { 3519 return 0; 3520 } 3521 insn->opcode = (short) JIT_OP_BR; 3522 insn->flags = JIT_INSN_DEST_IS_LABEL; 3523 insn->dest = (jit_value_t) *label; 3524 func->builder->current_block->ends_in_dead = 1; 3525 3526 return jit_insn_new_block(func); 3527 } 3528 3529 /*@ 3530 * @deftypefun int jit_insn_branch_if (jit_function_t @var{func}, jit_value_t @var{value}, jit_label_t *@var{label}) 3531 * Terminate the current block by branching to a specific label if 3532 * the specified value is non-zero. Returns zero if out of memory. 3533 * 3534 * If @var{value} refers to a conditional expression that was created 3535 * by @code{jit_insn_eq}, @code{jit_insn_ne}, etc, then the conditional 3536 * expression will be replaced by an appropriate conditional branch 3537 * instruction. 3538 * @end deftypefun 3539 @*/ 3540 int 3541 jit_insn_branch_if(jit_function_t func, jit_value_t value, jit_label_t *label) 3542 { 3543 /* Ensure that we have a function builder */ 3544 if(!_jit_function_ensure_builder(func)) 3545 { 3546 return 0; 3547 } 3548 3549 /* Flush any stack pops that were deferred previously */ 3550 if(!jit_insn_flush_defer_pop(func, 0)) 3551 { 3552 return 0; 3553 } 3554 3555 /* Allocate a new label identifier, if necessary */ 3556 if(*label == jit_label_undefined) 3557 { 3558 *label = func->builder->next_label++; 3559 } 3560 3561 /* If the condition is constant, then convert it into either 3562 an unconditional branch or a fall-through, as appropriate */ 3563 if(jit_value_is_constant(value)) 3564 { 3565 if(jit_value_is_true(value)) 3566 { 3567 return jit_insn_branch(func, label); 3568 } 3569 else 3570 { 3571 return 1; 3572 } 3573 } 3574 3575 /* Determine if we can replace a previous comparison instruction */ 3576 int opcode; 3577 jit_value_t value1; 3578 jit_value_t value2; 3579 jit_block_t block = func->builder->current_block; 3580 jit_insn_t prev = _jit_block_get_last(block); 3581 if(value->is_temporary && prev && prev->dest == value) 3582 { 3583 opcode = prev->opcode; 3584 if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV) 3585 { 3586 switch(opcode) 3587 { 3588 case JIT_OP_IEQ: opcode = JIT_OP_BR_IEQ; break; 3589 case JIT_OP_INE: opcode = JIT_OP_BR_INE; break; 3590 case JIT_OP_ILT: opcode = JIT_OP_BR_ILT; break; 3591 case JIT_OP_ILT_UN: opcode = JIT_OP_BR_ILT_UN; break; 3592 case JIT_OP_ILE: opcode = JIT_OP_BR_ILE; break; 3593 case JIT_OP_ILE_UN: opcode = JIT_OP_BR_ILE_UN; break; 3594 case JIT_OP_IGT: opcode = JIT_OP_BR_IGT; break; 3595 case JIT_OP_IGT_UN: opcode = JIT_OP_BR_IGT_UN; break; 3596 case JIT_OP_IGE: opcode = JIT_OP_BR_IGE; break; 3597 case JIT_OP_IGE_UN: opcode = JIT_OP_BR_IGE_UN; break; 3598 case JIT_OP_LEQ: opcode = JIT_OP_BR_LEQ; break; 3599 case JIT_OP_LNE: opcode = JIT_OP_BR_LNE; break; 3600 case JIT_OP_LLT: opcode = JIT_OP_BR_LLT; break; 3601 case JIT_OP_LLT_UN: opcode = JIT_OP_BR_LLT_UN; break; 3602 case JIT_OP_LLE: opcode = JIT_OP_BR_LLE; break; 3603 case JIT_OP_LLE_UN: opcode = JIT_OP_BR_LLE_UN; break; 3604 case JIT_OP_LGT: opcode = JIT_OP_BR_LGT; break; 3605 case JIT_OP_LGT_UN: opcode = JIT_OP_BR_LGT_UN; break; 3606 case JIT_OP_LGE: opcode = JIT_OP_BR_LGE; break; 3607 case JIT_OP_LGE_UN: opcode = JIT_OP_BR_LGE_UN; break; 3608 case JIT_OP_FEQ: opcode = JIT_OP_BR_FEQ; break; 3609 case JIT_OP_FNE: opcode = JIT_OP_BR_FNE; break; 3610 case JIT_OP_FLT: opcode = JIT_OP_BR_FLT; break; 3611 case JIT_OP_FLE: opcode = JIT_OP_BR_FLE; break; 3612 case JIT_OP_FGT: opcode = JIT_OP_BR_FGT; break; 3613 case JIT_OP_FGE: opcode = JIT_OP_BR_FGE; break; 3614 case JIT_OP_FLT_INV: opcode = JIT_OP_BR_FLT_INV; break; 3615 case JIT_OP_FLE_INV: opcode = JIT_OP_BR_FLE_INV; break; 3616 case JIT_OP_FGT_INV: opcode = JIT_OP_BR_FGT_INV; break; 3617 case JIT_OP_FGE_INV: opcode = JIT_OP_BR_FGE_INV; break; 3618 case JIT_OP_DEQ: opcode = JIT_OP_BR_DEQ; break; 3619 case JIT_OP_DNE: opcode = JIT_OP_BR_DNE; break; 3620 case JIT_OP_DLT: opcode = JIT_OP_BR_DLT; break; 3621 case JIT_OP_DLE: opcode = JIT_OP_BR_DLE; break; 3622 case JIT_OP_DGT: opcode = JIT_OP_BR_DGT; break; 3623 case JIT_OP_DGE: opcode = JIT_OP_BR_DGE; break; 3624 case JIT_OP_DLT_INV: opcode = JIT_OP_BR_DLT_INV; break; 3625 case JIT_OP_DLE_INV: opcode = JIT_OP_BR_DLE_INV; break; 3626 case JIT_OP_DGT_INV: opcode = JIT_OP_BR_DGT_INV; break; 3627 case JIT_OP_DGE_INV: opcode = JIT_OP_BR_DGE_INV; break; 3628 case JIT_OP_NFEQ: opcode = JIT_OP_BR_NFEQ; break; 3629 case JIT_OP_NFNE: opcode = JIT_OP_BR_NFNE; break; 3630 case JIT_OP_NFLT: opcode = JIT_OP_BR_NFLT; break; 3631 case JIT_OP_NFLE: opcode = JIT_OP_BR_NFLE; break; 3632 case JIT_OP_NFGT: opcode = JIT_OP_BR_NFGT; break; 3633 case JIT_OP_NFGE: opcode = JIT_OP_BR_NFGE; break; 3634 case JIT_OP_NFLT_INV: opcode = JIT_OP_BR_NFLT_INV; break; 3635 case JIT_OP_NFLE_INV: opcode = JIT_OP_BR_NFLE_INV; break; 3636 case JIT_OP_NFGT_INV: opcode = JIT_OP_BR_NFGT_INV; break; 3637 case JIT_OP_NFGE_INV: opcode = JIT_OP_BR_NFGE_INV; break; 3638 } 3639 3640 /* Save the values from the previous insn because *prev might 3641 become invalid if the call to _jit_block_add_insn triggers 3642 a reallocation of the insns array. */ 3643 value1 = prev->value1; 3644 value2 = prev->value2; 3645 3646 /* Add a new branch instruction */ 3647 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 3648 if(!insn) 3649 { 3650 return 0; 3651 } 3652 insn->opcode = (short) opcode; 3653 insn->flags = JIT_INSN_DEST_IS_LABEL; 3654 insn->dest = (jit_value_t) *label; 3655 insn->value1 = value1; 3656 jit_value_ref(func, value1); 3657 insn->value2 = value2; 3658 jit_value_ref(func, value2); 3659 3660 goto add_block; 3661 } 3662 } 3663 3664 /* Coerce the result to something comparable */ 3665 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 3666 value = jit_insn_convert(func, value, type, 0); 3667 if(!value) 3668 { 3669 return 0; 3670 } 3671 3672 /* Determine the opcode */ 3673 switch(type->kind) 3674 { 3675 case JIT_TYPE_INT: 3676 case JIT_TYPE_UINT: 3677 opcode = JIT_OP_BR_ITRUE; 3678 value2 = 0; 3679 break; 3680 case JIT_TYPE_LONG: 3681 case JIT_TYPE_ULONG: 3682 opcode = JIT_OP_BR_LTRUE; 3683 value2 = 0; 3684 break; 3685 case JIT_TYPE_FLOAT32: 3686 opcode = JIT_OP_BR_FNE; 3687 value2 = jit_value_create_float32_constant(func, jit_type_float32, 3688 (jit_float32) 0.0); 3689 if(!value2) 3690 { 3691 return 0; 3692 } 3693 break; 3694 case JIT_TYPE_FLOAT64: 3695 opcode = JIT_OP_BR_DNE; 3696 value2 = jit_value_create_float64_constant(func, jit_type_float64, 3697 (jit_float64) 0.0); 3698 if(!value2) 3699 { 3700 return 0; 3701 } 3702 break; 3703 case JIT_TYPE_NFLOAT: 3704 type = jit_type_nfloat; 3705 opcode = JIT_OP_BR_NFNE; 3706 value2 = jit_value_create_nfloat_constant(func, jit_type_nfloat, 3707 (jit_nfloat) 0.0); 3708 if(!value2) 3709 { 3710 return 0; 3711 } 3712 break; 3713 default: 3714 return 0; 3715 } 3716 3717 /* Add a new branch instruction */ 3718 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 3719 if(!insn) 3720 { 3721 return 0; 3722 } 3723 insn->opcode = (short) opcode; 3724 insn->flags = JIT_INSN_DEST_IS_LABEL; 3725 insn->dest = (jit_value_t) *label; 3726 insn->value1 = value; 3727 jit_value_ref(func, value); 3728 if(value2) 3729 { 3730 insn->value2 = value2; 3731 jit_value_ref(func, value2); 3732 } 3733 3734 add_block: 3735 /* Add a new block for the fall-through case */ 3736 return jit_insn_new_block(func); 3737 } 3738 3739 /*@ 3740 * @deftypefun int jit_insn_branch_if_not (jit_function_t @var{func}, jit_value_t @var{value}, jit_label_t *@var{label}) 3741 * Terminate the current block by branching to a specific label if 3742 * the specified value is zero. Returns zero if out of memory. 3743 * 3744 * If @var{value} refers to a conditional expression that was created 3745 * by @code{jit_insn_eq}, @code{jit_insn_ne}, etc, then the conditional 3746 * expression will be followed by an appropriate conditional branch 3747 * instruction, instead of a value load. 3748 * @end deftypefun 3749 @*/ 3750 int 3751 jit_insn_branch_if_not(jit_function_t func, jit_value_t value, jit_label_t *label) 3752 { 3753 /* Ensure that we have a function builder */ 3754 if(!_jit_function_ensure_builder(func)) 3755 { 3756 return 0; 3757 } 3758 3759 /* Flush any stack pops that were deferred previously */ 3760 if(!jit_insn_flush_defer_pop(func, 0)) 3761 { 3762 return 0; 3763 } 3764 3765 /* Allocate a new label identifier, if necessary */ 3766 if(*label == jit_label_undefined) 3767 { 3768 *label = func->builder->next_label++; 3769 } 3770 3771 /* If the condition is constant, then convert it into either 3772 an unconditional branch or a fall-through, as appropriate */ 3773 if(jit_value_is_constant(value)) 3774 { 3775 if(!jit_value_is_true(value)) 3776 { 3777 return jit_insn_branch(func, label); 3778 } 3779 else 3780 { 3781 return 1; 3782 } 3783 } 3784 3785 /* Determine if we can duplicate a previous comparison instruction */ 3786 int opcode; 3787 jit_value_t value1; 3788 jit_value_t value2; 3789 jit_block_t block = func->builder->current_block; 3790 jit_insn_t prev = _jit_block_get_last(block); 3791 if(value->is_temporary && prev && prev->dest == value) 3792 { 3793 opcode = prev->opcode; 3794 if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV) 3795 { 3796 switch(opcode) 3797 { 3798 case JIT_OP_IEQ: opcode = JIT_OP_BR_INE; break; 3799 case JIT_OP_INE: opcode = JIT_OP_BR_IEQ; break; 3800 case JIT_OP_ILT: opcode = JIT_OP_BR_IGE; break; 3801 case JIT_OP_ILT_UN: opcode = JIT_OP_BR_IGE_UN; break; 3802 case JIT_OP_ILE: opcode = JIT_OP_BR_IGT; break; 3803 case JIT_OP_ILE_UN: opcode = JIT_OP_BR_IGT_UN; break; 3804 case JIT_OP_IGT: opcode = JIT_OP_BR_ILE; break; 3805 case JIT_OP_IGT_UN: opcode = JIT_OP_BR_ILE_UN; break; 3806 case JIT_OP_IGE: opcode = JIT_OP_BR_ILT; break; 3807 case JIT_OP_IGE_UN: opcode = JIT_OP_BR_ILT_UN; break; 3808 case JIT_OP_LEQ: opcode = JIT_OP_BR_LNE; break; 3809 case JIT_OP_LNE: opcode = JIT_OP_BR_LEQ; break; 3810 case JIT_OP_LLT: opcode = JIT_OP_BR_LGE; break; 3811 case JIT_OP_LLT_UN: opcode = JIT_OP_BR_LGE_UN; break; 3812 case JIT_OP_LLE: opcode = JIT_OP_BR_LGT; break; 3813 case JIT_OP_LLE_UN: opcode = JIT_OP_BR_LGT_UN; break; 3814 case JIT_OP_LGT: opcode = JIT_OP_BR_LLE; break; 3815 case JIT_OP_LGT_UN: opcode = JIT_OP_BR_LLE_UN; break; 3816 case JIT_OP_LGE: opcode = JIT_OP_BR_LLT; break; 3817 case JIT_OP_LGE_UN: opcode = JIT_OP_BR_LLT_UN; break; 3818 case JIT_OP_FEQ: opcode = JIT_OP_BR_FNE; break; 3819 case JIT_OP_FNE: opcode = JIT_OP_BR_FEQ; break; 3820 case JIT_OP_FLT: opcode = JIT_OP_BR_FGE_INV; break; 3821 case JIT_OP_FLE: opcode = JIT_OP_BR_FGT_INV; break; 3822 case JIT_OP_FGT: opcode = JIT_OP_BR_FLE_INV; break; 3823 case JIT_OP_FGE: opcode = JIT_OP_BR_FLT_INV; break; 3824 case JIT_OP_FLT_INV: opcode = JIT_OP_BR_FGE; break; 3825 case JIT_OP_FLE_INV: opcode = JIT_OP_BR_FGT; break; 3826 case JIT_OP_FGT_INV: opcode = JIT_OP_BR_FLE; break; 3827 case JIT_OP_FGE_INV: opcode = JIT_OP_BR_FLT; break; 3828 case JIT_OP_DEQ: opcode = JIT_OP_BR_DNE; break; 3829 case JIT_OP_DNE: opcode = JIT_OP_BR_DEQ; break; 3830 case JIT_OP_DLT: opcode = JIT_OP_BR_DGE_INV; break; 3831 case JIT_OP_DLE: opcode = JIT_OP_BR_DGT_INV; break; 3832 case JIT_OP_DGT: opcode = JIT_OP_BR_DLE_INV; break; 3833 case JIT_OP_DGE: opcode = JIT_OP_BR_DLT_INV; break; 3834 case JIT_OP_DLT_INV: opcode = JIT_OP_BR_DGE; break; 3835 case JIT_OP_DLE_INV: opcode = JIT_OP_BR_DGT; break; 3836 case JIT_OP_DGT_INV: opcode = JIT_OP_BR_DLE; break; 3837 case JIT_OP_DGE_INV: opcode = JIT_OP_BR_DLT; break; 3838 case JIT_OP_NFEQ: opcode = JIT_OP_BR_NFNE; break; 3839 case JIT_OP_NFNE: opcode = JIT_OP_BR_NFEQ; break; 3840 case JIT_OP_NFLT: opcode = JIT_OP_BR_NFGE_INV; break; 3841 case JIT_OP_NFLE: opcode = JIT_OP_BR_NFGT_INV; break; 3842 case JIT_OP_NFGT: opcode = JIT_OP_BR_NFLE_INV; break; 3843 case JIT_OP_NFGE: opcode = JIT_OP_BR_NFLT_INV; break; 3844 case JIT_OP_NFLT_INV: opcode = JIT_OP_BR_NFGE; break; 3845 case JIT_OP_NFLE_INV: opcode = JIT_OP_BR_NFGT; break; 3846 case JIT_OP_NFGT_INV: opcode = JIT_OP_BR_NFLE; break; 3847 case JIT_OP_NFGE_INV: opcode = JIT_OP_BR_NFLT; break; 3848 } 3849 3850 /* Save the values from the previous insn because *prev might 3851 become invalid if the call to _jit_block_add_insn triggers 3852 a reallocation of the insns array. */ 3853 value1 = prev->value1; 3854 value2 = prev->value2; 3855 3856 /* Add a new branch instruction */ 3857 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 3858 if(!insn) 3859 { 3860 return 0; 3861 } 3862 insn->opcode = (short) opcode; 3863 insn->flags = JIT_INSN_DEST_IS_LABEL; 3864 insn->dest = (jit_value_t) *label; 3865 insn->value1 = value1; 3866 jit_value_ref(func, value1); 3867 insn->value2 = value2; 3868 jit_value_ref(func, value2); 3869 3870 goto add_block; 3871 } 3872 } 3873 3874 /* Coerce the result to something comparable */ 3875 jit_type_t type = jit_type_promote_int(jit_type_normalize(value->type)); 3876 value = jit_insn_convert(func, value, type, 0); 3877 if(!value) 3878 { 3879 return 0; 3880 } 3881 3882 /* Determine the opcode */ 3883 switch(type->kind) 3884 { 3885 case JIT_TYPE_INT: 3886 case JIT_TYPE_UINT: 3887 opcode = JIT_OP_BR_IFALSE; 3888 value2 = 0; 3889 break; 3890 case JIT_TYPE_LONG: 3891 case JIT_TYPE_ULONG: 3892 opcode = JIT_OP_BR_LFALSE; 3893 value2 = 0; 3894 break; 3895 case JIT_TYPE_FLOAT32: 3896 opcode = JIT_OP_BR_FEQ; 3897 value2 = jit_value_create_float32_constant(func, jit_type_float32, 3898 (jit_float32) 0.0); 3899 if(!value2) 3900 { 3901 return 0; 3902 } 3903 break; 3904 case JIT_TYPE_FLOAT64: 3905 opcode = JIT_OP_BR_DEQ; 3906 value2 = jit_value_create_float64_constant(func, jit_type_float64, 3907 (jit_float64) 0.0); 3908 if(!value2) 3909 { 3910 return 0; 3911 } 3912 break; 3913 case JIT_TYPE_NFLOAT: 3914 opcode = JIT_OP_BR_NFEQ; 3915 value2 = jit_value_create_nfloat_constant(func, jit_type_nfloat, 3916 (jit_nfloat) 0.0); 3917 if(!value2) 3918 { 3919 return 0; 3920 } 3921 break; 3922 default: 3923 return 0; 3924 } 3925 3926 /* Add a new branch instruction */ 3927 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 3928 if(!insn) 3929 { 3930 return 0; 3931 } 3932 insn->opcode = (short) opcode; 3933 insn->flags = JIT_INSN_DEST_IS_LABEL; 3934 insn->dest = (jit_value_t) *label; 3935 insn->value1 = value; 3936 jit_value_ref(func, value); 3937 if(value2) 3938 { 3939 insn->value2 = value2; 3940 jit_value_ref(func, value2); 3941 } 3942 3943 add_block: 3944 /* Add a new block for the fall-through case */ 3945 return jit_insn_new_block(func); 3946 } 3947 3948 /*@ 3949 * @deftypefun int jit_insn_jump_table (jit_function_t @var{func}, jit_value_t @var{value}, jit_label_t *@var{labels}, unsigned int @var{num_labels}) 3950 * Branch to a label from the @var{labels} table. The @var{value} is the 3951 * index of the label. It is allowed to have identical labels in the table. 3952 * If an entry in the table has @code{jit_label_undefined} value then it is 3953 * replaced with a newly allocated label. 3954 * @end deftypefun 3955 @*/ 3956 int 3957 jit_insn_jump_table(jit_function_t func, jit_value_t value, 3958 jit_label_t *labels, unsigned int num_labels) 3959 { 3960 /* Bail out if the parameters are invalid */ 3961 if(!num_labels) 3962 { 3963 return 0; 3964 } 3965 3966 /* Ensure that we have a function builder */ 3967 if(!_jit_function_ensure_builder(func)) 3968 { 3969 return 0; 3970 } 3971 3972 /* Flush any stack pops that were deferred previously */ 3973 if(!jit_insn_flush_defer_pop(func, 0)) 3974 { 3975 return 0; 3976 } 3977 3978 /* Allocate new label identifiers, if necessary */ 3979 unsigned int index; 3980 for(index = 0; index < num_labels; index++) 3981 { 3982 if(labels[index] == jit_label_undefined) 3983 { 3984 labels[index] = func->builder->next_label++; 3985 } 3986 } 3987 3988 /* If the condition is constant, then convert it into either 3989 an unconditional branch or a fall-through, as appropriate */ 3990 if(jit_value_is_constant(value)) 3991 { 3992 index = jit_value_get_nint_constant(value); 3993 if(index < num_labels && index >= 0) 3994 { 3995 return jit_insn_branch(func, &labels[index]); 3996 } 3997 else 3998 { 3999 return 1; 4000 } 4001 } 4002 4003 jit_label_t *new_labels = jit_malloc(num_labels * sizeof(jit_label_t)); 4004 if(!new_labels) 4005 { 4006 return 0; 4007 } 4008 for(index = 0; index < num_labels; index++) 4009 { 4010 new_labels[index] = labels[index]; 4011 } 4012 4013 jit_value_t value_labels = 4014 jit_value_create_nint_constant(func, jit_type_void_ptr, (jit_nint) new_labels); 4015 if(!value_labels) 4016 { 4017 jit_free(new_labels); 4018 return 0; 4019 } 4020 value_labels->free_address = 1; 4021 4022 jit_value_t value_num_labels = 4023 jit_value_create_nint_constant(func, jit_type_uint, num_labels); 4024 if(!value_num_labels) 4025 { 4026 _jit_value_free(value_labels); 4027 return 0; 4028 } 4029 4030 /* Add a new branch instruction */ 4031 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 4032 if(!insn) 4033 { 4034 return 0; 4035 } 4036 insn->opcode = JIT_OP_JUMP_TABLE; 4037 insn->flags = JIT_INSN_DEST_IS_VALUE; 4038 insn->dest = value; 4039 jit_value_ref(func, value); 4040 insn->value1 = value_labels; 4041 insn->value2 = value_num_labels; 4042 4043 /* Add a new block for the fall-through case */ 4044 return jit_insn_new_block(func); 4045 } 4046 4047 /*@ 4048 * @deftypefun jit_value_t jit_insn_address_of (jit_function_t @var{func}, jit_value_t @var{value1}) 4049 * Get the address of a value into a new temporary. 4050 * @end deftypefun 4051 @*/ 4052 jit_value_t 4053 jit_insn_address_of(jit_function_t func, jit_value_t value) 4054 { 4055 if(jit_value_is_constant(value)) 4056 { 4057 return 0; 4058 } 4059 jit_type_t type = jit_type_create_pointer(jit_value_get_type(value), 1); 4060 if(!type) 4061 { 4062 return 0; 4063 } 4064 jit_value_set_addressable(value); 4065 jit_value_t result = apply_unary(func, JIT_OP_ADDRESS_OF, value, type); 4066 jit_type_free(type); 4067 return result; 4068 } 4069 4070 /*@ 4071 * @deftypefun jit_value_t jit_insn_address_of_label (jit_function_t @var{func}, jit_label_t *@var{label}) 4072 * Get the address of @var{label} into a new temporary. This is typically 4073 * used for exception handling, to track where in a function an exception 4074 * was actually thrown. 4075 * @end deftypefun 4076 @*/ 4077 jit_value_t 4078 jit_insn_address_of_label(jit_function_t func, jit_label_t *label) 4079 { 4080 /* Ensure that we have a function builder */ 4081 if(!_jit_function_ensure_builder(func)) 4082 { 4083 return 0; 4084 } 4085 4086 /* Allocate a new label identifier, if necessary */ 4087 if(*label == jit_label_undefined) 4088 { 4089 *label = func->builder->next_label++; 4090 } 4091 if(!_jit_block_record_label_flags(func, *label, JIT_LABEL_ADDRESS_OF)) 4092 { 4093 return 0; 4094 } 4095 4096 /* Add a new address-of-label instruction */ 4097 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 4098 if(!insn) 4099 { 4100 return 0; 4101 } 4102 jit_value_t dest = jit_value_create(func, jit_type_void_ptr); 4103 if(!dest) 4104 { 4105 return 0; 4106 } 4107 insn->opcode = (short) JIT_OP_ADDRESS_OF_LABEL; 4108 insn->flags = JIT_INSN_VALUE1_IS_LABEL; 4109 insn->dest = dest; 4110 insn->value1 = (jit_value_t) *label; 4111 4112 return dest; 4113 } 4114 4115 /* 4116 * Information about the opcodes for a particular conversion. 4117 */ 4118 typedef struct jit_convert_info 4119 { 4120 int cvt1; 4121 jit_type_t type1; 4122 int cvt2; 4123 jit_type_t type2; 4124 int cvt3; 4125 jit_type_t type3; 4126 4127 } jit_convert_info_t; 4128 4129 #define CVT(opcode,name) opcode, (jit_type_t) &_jit_type_##name##_def 4130 #define CVT_NONE 0, 0 4131 4132 /* 4133 * Intrinsic equivalents for the conversion opcodes. 4134 */ 4135 typedef struct jit_convert_intrinsic 4136 { 4137 const char *name; 4138 void *func; 4139 jit_intrinsic_descr_t descr; 4140 4141 } jit_convert_intrinsic_t; 4142 4143 #define CVT_INTRINSIC_NULL \ 4144 {0, 0, {0, 0, 0, 0}} 4145 4146 #define CVT_INTRINSIC(name, intype, outtype) \ 4147 { #name, (void *) name, \ 4148 { (jit_type_t) &_jit_type_##outtype##_def, 0, \ 4149 (jit_type_t) &_jit_type_##intype##_def, 0 } } 4150 4151 #define CVT_INTRINSIC_CHECK(name, intype, outtype) \ 4152 { #name, (void *) name, \ 4153 { (jit_type_t) &_jit_type_int_def, \ 4154 (jit_type_t) &_jit_type_##outtype##_def, \ 4155 (jit_type_t) &_jit_type_##intype##_def, 0 } } 4156 4157 static jit_convert_intrinsic_t const convert_intrinsics[] = { 4158 CVT_INTRINSIC(jit_int_to_sbyte, int, int), 4159 CVT_INTRINSIC(jit_int_to_ubyte, int, int), 4160 CVT_INTRINSIC(jit_int_to_short, int, int), 4161 CVT_INTRINSIC(jit_int_to_ushort, int, int), 4162 #ifdef JIT_NATIVE_INT32 4163 CVT_INTRINSIC(jit_int_to_int, int, int), 4164 CVT_INTRINSIC(jit_uint_to_uint, uint, uint), 4165 #else 4166 CVT_INTRINSIC(jit_long_to_int, long, int), 4167 CVT_INTRINSIC(jit_long_to_uint, long, uint), 4168 #endif 4169 CVT_INTRINSIC_CHECK(jit_int_to_sbyte_ovf, int, int), 4170 CVT_INTRINSIC_CHECK(jit_int_to_ubyte_ovf, int, int), 4171 CVT_INTRINSIC_CHECK(jit_int_to_short_ovf, int, int), 4172 CVT_INTRINSIC_CHECK(jit_int_to_ushort_ovf, int, int), 4173 #ifdef JIT_NATIVE_INT32 4174 CVT_INTRINSIC_CHECK(jit_int_to_int_ovf, int, int), 4175 CVT_INTRINSIC_CHECK(jit_uint_to_uint_ovf, uint, uint), 4176 #else 4177 CVT_INTRINSIC_CHECK(jit_long_to_int_ovf, long, int), 4178 CVT_INTRINSIC_CHECK(jit_long_to_uint_ovf, long, uint), 4179 #endif 4180 CVT_INTRINSIC(jit_long_to_uint, long, uint), 4181 CVT_INTRINSIC(jit_int_to_long, int, long), 4182 CVT_INTRINSIC(jit_uint_to_long, uint, long), 4183 CVT_INTRINSIC_CHECK(jit_long_to_uint_ovf, long, uint), 4184 CVT_INTRINSIC_CHECK(jit_long_to_int_ovf, long, int), 4185 CVT_INTRINSIC_CHECK(jit_ulong_to_long_ovf, ulong, long), 4186 CVT_INTRINSIC_CHECK(jit_long_to_ulong_ovf, long, ulong), 4187 CVT_INTRINSIC(jit_float32_to_int, float32, int), 4188 CVT_INTRINSIC(jit_float32_to_uint, float32, uint), 4189 CVT_INTRINSIC(jit_float32_to_long, float32, long), 4190 CVT_INTRINSIC(jit_float32_to_ulong, float32, ulong), 4191 CVT_INTRINSIC_CHECK(jit_float32_to_int_ovf, float32, int), 4192 CVT_INTRINSIC_CHECK(jit_float32_to_uint_ovf, float32, uint), 4193 CVT_INTRINSIC_CHECK(jit_float32_to_long_ovf, float32, long), 4194 CVT_INTRINSIC_CHECK(jit_float32_to_ulong_ovf, float32, ulong), 4195 CVT_INTRINSIC(jit_int_to_float32, int, float32), 4196 CVT_INTRINSIC(jit_uint_to_float32, uint, float32), 4197 CVT_INTRINSIC(jit_long_to_float32, long, float32), 4198 CVT_INTRINSIC(jit_ulong_to_float32, ulong, float32), 4199 CVT_INTRINSIC(jit_float32_to_float64, float32, float64), 4200 CVT_INTRINSIC(jit_float64_to_int, float64, int), 4201 CVT_INTRINSIC(jit_float64_to_uint, float64, uint), 4202 CVT_INTRINSIC(jit_float64_to_long, float64, long), 4203 CVT_INTRINSIC(jit_float64_to_ulong, float64, ulong), 4204 CVT_INTRINSIC_CHECK(jit_float64_to_int_ovf, float64, int), 4205 CVT_INTRINSIC_CHECK(jit_float64_to_uint_ovf, float64, uint), 4206 CVT_INTRINSIC_CHECK(jit_float64_to_long_ovf, float64, long), 4207 CVT_INTRINSIC_CHECK(jit_float64_to_ulong_ovf, float64, ulong), 4208 CVT_INTRINSIC(jit_int_to_float64, int, float64), 4209 CVT_INTRINSIC(jit_uint_to_float64, uint, float64), 4210 CVT_INTRINSIC(jit_long_to_float64, long, float64), 4211 CVT_INTRINSIC(jit_ulong_to_float64, ulong, float64), 4212 CVT_INTRINSIC(jit_float64_to_float32, float64, float32), 4213 CVT_INTRINSIC(jit_nfloat_to_int, nfloat, int), 4214 CVT_INTRINSIC(jit_nfloat_to_uint, nfloat, uint), 4215 CVT_INTRINSIC(jit_nfloat_to_long, nfloat, long), 4216 CVT_INTRINSIC(jit_nfloat_to_ulong, nfloat, ulong), 4217 CVT_INTRINSIC_CHECK(jit_nfloat_to_int_ovf, nfloat, int), 4218 CVT_INTRINSIC_CHECK(jit_nfloat_to_uint_ovf, nfloat, uint), 4219 CVT_INTRINSIC_CHECK(jit_nfloat_to_long_ovf, nfloat, long), 4220 CVT_INTRINSIC_CHECK(jit_nfloat_to_ulong_ovf, nfloat, ulong), 4221 CVT_INTRINSIC(jit_int_to_nfloat, int, nfloat), 4222 CVT_INTRINSIC(jit_uint_to_nfloat, uint, nfloat), 4223 CVT_INTRINSIC(jit_long_to_nfloat, long, nfloat), 4224 CVT_INTRINSIC(jit_ulong_to_nfloat, ulong, nfloat), 4225 CVT_INTRINSIC(jit_nfloat_to_float32, nfloat, float32), 4226 CVT_INTRINSIC(jit_nfloat_to_float64, nfloat, float64), 4227 CVT_INTRINSIC(jit_float32_to_nfloat, float32, nfloat), 4228 CVT_INTRINSIC(jit_float64_to_nfloat, float64, nfloat) 4229 }; 4230 4231 /* 4232 * Apply a unary conversion operator. 4233 */ 4234 static jit_value_t 4235 apply_conversion(jit_function_t func, int oper, jit_value_t value, 4236 jit_type_t result_type) 4237 { 4238 /* Set the "may_throw" flag if the conversion may throw an exception */ 4239 if(oper < sizeof(convert_intrinsics) / sizeof(jit_convert_intrinsic_t) 4240 && convert_intrinsics[oper - 1].descr.ptr_result_type) 4241 { 4242 func->builder->may_throw = 1; 4243 } 4244 4245 /* Bail out early if the conversion opcode is supported by the back end */ 4246 if(_jit_opcode_is_supported(oper)) 4247 { 4248 return apply_unary(func, oper, value, result_type); 4249 } 4250 4251 /* Call the appropriate intrinsic method */ 4252 return jit_insn_call_intrinsic(func, convert_intrinsics[oper - 1].name, 4253 convert_intrinsics[oper - 1].func, 4254 &convert_intrinsics[oper - 1].descr, 4255 value, 0); 4256 } 4257 4258 /*@ 4259 * @deftypefun jit_value_t jit_insn_convert (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{type}, int @var{overflow_check}) 4260 * Convert the contents of a value into a new type, with optional 4261 * overflow checking. 4262 * @end deftypefun 4263 @*/ 4264 jit_value_t 4265 jit_insn_convert(jit_function_t func, jit_value_t value, jit_type_t type, 4266 int overflow_check) 4267 { 4268 /* Normalize the source and destination types */ 4269 jit_type_t vtype = jit_type_normalize(value->type); 4270 type = jit_type_normalize(type); 4271 4272 /* If the types are identical, then return the source value as-is */ 4273 if(type == vtype) 4274 { 4275 return value; 4276 } 4277 4278 /* If the source is a constant, then perform a constant conversion. 4279 If an overflow might result, we perform the computation at runtime */ 4280 if(jit_value_is_constant(value)) 4281 { 4282 jit_constant_t const_value; 4283 const_value = jit_value_get_constant(value); 4284 if(jit_constant_convert(&const_value, &const_value, type, overflow_check)) 4285 { 4286 return jit_value_create_constant(func, &const_value); 4287 } 4288 } 4289 4290 /* Promote the source type, to reduce the number of cases in 4291 the switch statement below */ 4292 vtype = jit_type_promote_int(vtype); 4293 4294 /* Determine how to perform the conversion */ 4295 const jit_convert_info_t *opcode_map = 0; 4296 switch(type->kind) 4297 { 4298 case JIT_TYPE_SBYTE: 4299 { 4300 /* Convert the value into a signed byte */ 4301 static jit_convert_info_t const to_sbyte[] = { 4302 /* from signed byte */ 4303 /* from signed short */ 4304 /* from signed int */ 4305 { CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4306 CVT_NONE, 4307 CVT_NONE }, 4308 { CVT(JIT_OP_CHECK_SBYTE, sbyte), 4309 CVT_NONE, 4310 CVT_NONE }, 4311 /* from unsigned byte */ 4312 /* from unsigned short */ 4313 /* from unsigned int */ 4314 { CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4315 CVT_NONE, 4316 CVT_NONE }, 4317 { CVT(JIT_OP_CHECK_INT, int), 4318 CVT(JIT_OP_CHECK_SBYTE, sbyte), 4319 CVT_NONE }, 4320 /* from signed long */ 4321 { CVT(JIT_OP_LOW_WORD, int), 4322 CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4323 CVT_NONE }, 4324 { CVT(JIT_OP_CHECK_SIGNED_LOW_WORD, int), 4325 CVT(JIT_OP_CHECK_SBYTE, sbyte), 4326 CVT_NONE }, 4327 /* from unsigned long */ 4328 { CVT(JIT_OP_LOW_WORD, int), 4329 CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4330 CVT_NONE }, 4331 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4332 CVT(JIT_OP_CHECK_INT, int), 4333 CVT(JIT_OP_CHECK_SBYTE, sbyte) }, 4334 /* from 32-bit float */ 4335 { CVT(JIT_OP_FLOAT32_TO_INT, int), 4336 CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4337 CVT_NONE }, 4338 { CVT(JIT_OP_CHECK_FLOAT32_TO_INT, int), 4339 CVT(JIT_OP_CHECK_SBYTE, sbyte), 4340 CVT_NONE }, 4341 /* from 64-bit float */ 4342 { CVT(JIT_OP_FLOAT64_TO_INT, int), 4343 CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4344 CVT_NONE }, 4345 { CVT(JIT_OP_CHECK_FLOAT64_TO_INT, int), 4346 CVT(JIT_OP_CHECK_SBYTE, sbyte), 4347 CVT_NONE }, 4348 /* from native float */ 4349 { CVT(JIT_OP_NFLOAT_TO_INT, int), 4350 CVT(JIT_OP_TRUNC_SBYTE, sbyte), 4351 CVT_NONE }, 4352 { CVT(JIT_OP_CHECK_NFLOAT_TO_INT, int), 4353 CVT(JIT_OP_CHECK_SBYTE, sbyte), 4354 CVT_NONE } 4355 }; 4356 opcode_map = to_sbyte; 4357 break; 4358 } 4359 4360 case JIT_TYPE_UBYTE: 4361 { 4362 /* Convert the value into an unsigned byte */ 4363 static jit_convert_info_t const to_ubyte[] = { 4364 /* from signed byte */ 4365 /* from signed short */ 4366 /* from signed int */ 4367 { CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4368 CVT_NONE, 4369 CVT_NONE }, 4370 { CVT(JIT_OP_CHECK_UBYTE, ubyte), 4371 CVT_NONE, 4372 CVT_NONE }, 4373 /* from unsigned byte */ 4374 /* from unsigned short */ 4375 /* from unsigned int */ 4376 { CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4377 CVT_NONE, 4378 CVT_NONE }, 4379 { CVT(JIT_OP_CHECK_UBYTE, ubyte), 4380 CVT_NONE, 4381 CVT_NONE }, 4382 /* from signed long */ 4383 { CVT(JIT_OP_LOW_WORD, int), 4384 CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4385 CVT_NONE }, 4386 { CVT(JIT_OP_CHECK_SIGNED_LOW_WORD, int), 4387 CVT(JIT_OP_CHECK_UBYTE, ubyte), 4388 CVT_NONE }, 4389 /* from unsigned long */ 4390 { CVT(JIT_OP_LOW_WORD, int), 4391 CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4392 CVT_NONE }, 4393 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4394 CVT(JIT_OP_CHECK_UBYTE, ubyte), 4395 CVT_NONE }, 4396 /* from 32-bit float */ 4397 { CVT(JIT_OP_FLOAT32_TO_INT, int), 4398 CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4399 CVT_NONE }, 4400 { CVT(JIT_OP_CHECK_FLOAT32_TO_INT, int), 4401 CVT(JIT_OP_CHECK_UBYTE, ubyte), 4402 CVT_NONE }, 4403 /* from 64-bit float */ 4404 { CVT(JIT_OP_FLOAT64_TO_INT, int), 4405 CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4406 CVT_NONE }, 4407 { CVT(JIT_OP_CHECK_FLOAT64_TO_INT, int), 4408 CVT(JIT_OP_CHECK_UBYTE, ubyte), 4409 CVT_NONE }, 4410 /* from native float */ 4411 { CVT(JIT_OP_NFLOAT_TO_INT, int), 4412 CVT(JIT_OP_TRUNC_UBYTE, ubyte), 4413 CVT_NONE }, 4414 { CVT(JIT_OP_CHECK_NFLOAT_TO_INT, int), 4415 CVT(JIT_OP_CHECK_UBYTE, ubyte), 4416 CVT_NONE } 4417 }; 4418 opcode_map = to_ubyte; 4419 break; 4420 } 4421 4422 case JIT_TYPE_SHORT: 4423 { 4424 /* Convert the value into a signed short */ 4425 static jit_convert_info_t const to_short[] = { 4426 /* from signed byte */ 4427 /* from signed short */ 4428 /* from signed int */ 4429 { CVT(JIT_OP_TRUNC_SHORT, short), 4430 CVT_NONE, 4431 CVT_NONE }, 4432 { CVT(JIT_OP_CHECK_SHORT, short), 4433 CVT_NONE, 4434 CVT_NONE }, 4435 /* from unsigned byte */ 4436 /* from unsigned short */ 4437 /* from unsigned int */ 4438 { CVT(JIT_OP_TRUNC_SHORT, short), 4439 CVT_NONE, 4440 CVT_NONE }, 4441 { CVT(JIT_OP_CHECK_INT, int), 4442 CVT(JIT_OP_CHECK_SHORT, short), 4443 CVT_NONE }, 4444 /* from signed long */ 4445 { CVT(JIT_OP_LOW_WORD, int), 4446 CVT(JIT_OP_TRUNC_SHORT, short), 4447 CVT_NONE }, 4448 { CVT(JIT_OP_CHECK_SIGNED_LOW_WORD, int), 4449 CVT(JIT_OP_CHECK_SHORT, short), 4450 CVT_NONE }, 4451 /* from unsigned long */ 4452 { CVT(JIT_OP_LOW_WORD, int), 4453 CVT(JIT_OP_TRUNC_SHORT, short), 4454 CVT_NONE }, 4455 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4456 CVT(JIT_OP_CHECK_INT, int), 4457 CVT(JIT_OP_CHECK_SHORT, short)}, 4458 /* from 32-bit float */ 4459 { CVT(JIT_OP_FLOAT32_TO_INT, int), 4460 CVT(JIT_OP_TRUNC_SHORT, short), 4461 CVT_NONE }, 4462 { CVT(JIT_OP_CHECK_FLOAT32_TO_INT, int), 4463 CVT(JIT_OP_CHECK_SHORT, short), 4464 CVT_NONE }, 4465 /* from 64-bit float */ 4466 { CVT(JIT_OP_FLOAT64_TO_INT, int), 4467 CVT(JIT_OP_TRUNC_SHORT, short), 4468 CVT_NONE }, 4469 { CVT(JIT_OP_CHECK_FLOAT64_TO_INT, int), 4470 CVT(JIT_OP_CHECK_SHORT, short), 4471 CVT_NONE }, 4472 /* from native float */ 4473 { CVT(JIT_OP_NFLOAT_TO_INT, int), 4474 CVT(JIT_OP_TRUNC_SHORT, short), 4475 CVT_NONE }, 4476 { CVT(JIT_OP_CHECK_NFLOAT_TO_INT, int), 4477 CVT(JIT_OP_CHECK_SHORT, short), 4478 CVT_NONE } 4479 }; 4480 opcode_map = to_short; 4481 break; 4482 } 4483 4484 case JIT_TYPE_USHORT: 4485 { 4486 /* Convert the value into an unsigned short */ 4487 static jit_convert_info_t const to_ushort[] = { 4488 /* from signed byte */ 4489 /* from signed short */ 4490 /* from signed int */ 4491 { CVT(JIT_OP_TRUNC_USHORT, ushort), 4492 CVT_NONE, 4493 CVT_NONE }, 4494 { CVT(JIT_OP_CHECK_USHORT, ushort), 4495 CVT_NONE, 4496 CVT_NONE }, 4497 /* from unsigned byte */ 4498 /* from unsigned short */ 4499 /* from unsigned int */ 4500 { CVT(JIT_OP_TRUNC_USHORT, ushort), 4501 CVT_NONE, 4502 CVT_NONE }, 4503 { CVT(JIT_OP_CHECK_USHORT, ushort), 4504 CVT_NONE, 4505 CVT_NONE }, 4506 /* from signed long */ 4507 { CVT(JIT_OP_LOW_WORD, int), 4508 CVT(JIT_OP_TRUNC_USHORT, ushort), 4509 CVT_NONE }, 4510 { CVT(JIT_OP_CHECK_SIGNED_LOW_WORD, int), 4511 CVT(JIT_OP_CHECK_USHORT, ushort), 4512 CVT_NONE }, 4513 /* from unsigned long */ 4514 { CVT(JIT_OP_LOW_WORD, int), 4515 CVT(JIT_OP_TRUNC_USHORT, ushort), 4516 CVT_NONE }, 4517 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4518 CVT(JIT_OP_CHECK_USHORT, ushort), 4519 CVT_NONE }, 4520 /* from 32-bit float */ 4521 { CVT(JIT_OP_FLOAT32_TO_INT, int), 4522 CVT(JIT_OP_TRUNC_USHORT, ushort), 4523 CVT_NONE }, 4524 { CVT(JIT_OP_CHECK_FLOAT32_TO_INT, int), 4525 CVT(JIT_OP_CHECK_USHORT, ushort), 4526 CVT_NONE }, 4527 /* from 64-bit float */ 4528 { CVT(JIT_OP_FLOAT64_TO_INT, int), 4529 CVT(JIT_OP_TRUNC_USHORT, ushort), 4530 CVT_NONE }, 4531 { CVT(JIT_OP_CHECK_FLOAT64_TO_INT, int), 4532 CVT(JIT_OP_CHECK_USHORT, ushort), 4533 CVT_NONE }, 4534 /* from native float */ 4535 { CVT(JIT_OP_NFLOAT_TO_INT, int), 4536 CVT(JIT_OP_TRUNC_USHORT, ushort), 4537 CVT_NONE }, 4538 { CVT(JIT_OP_CHECK_NFLOAT_TO_INT, int), 4539 CVT(JIT_OP_CHECK_USHORT, ushort), 4540 CVT_NONE } 4541 }; 4542 opcode_map = to_ushort; 4543 break; 4544 } 4545 4546 case JIT_TYPE_INT: 4547 { 4548 /* Convert the value into a signed int */ 4549 static jit_convert_info_t const to_int[] = { 4550 /* from signed byte */ 4551 /* from signed short */ 4552 /* from signed int */ 4553 { CVT(JIT_OP_COPY_INT, int), 4554 CVT_NONE, 4555 CVT_NONE}, 4556 { CVT(JIT_OP_COPY_INT, int), 4557 CVT_NONE, 4558 CVT_NONE}, 4559 /* from unsigned byte */ 4560 /* from unsigned short */ 4561 /* from unsigned int */ 4562 #ifndef JIT_NATIVE_INT32 4563 { CVT(JIT_OP_TRUNC_INT, int), 4564 CVT_NONE, 4565 CVT_NONE}, 4566 #else 4567 { CVT(JIT_OP_COPY_INT, int), 4568 CVT_NONE, 4569 CVT_NONE}, 4570 #endif 4571 { CVT(JIT_OP_CHECK_INT, int), 4572 CVT_NONE, 4573 CVT_NONE}, 4574 /* from signed long */ 4575 { CVT(JIT_OP_LOW_WORD, int), 4576 #ifndef JIT_NATIVE_INT32 4577 CVT(JIT_OP_TRUNC_INT, int), 4578 #else 4579 CVT_NONE, 4580 #endif 4581 CVT_NONE}, 4582 { CVT(JIT_OP_CHECK_SIGNED_LOW_WORD, int), 4583 CVT_NONE, 4584 CVT_NONE}, 4585 /* from unsigned long */ 4586 { CVT(JIT_OP_LOW_WORD, int), 4587 #ifndef JIT_NATIVE_INT32 4588 CVT(JIT_OP_TRUNC_INT, int), 4589 #else 4590 CVT_NONE, 4591 #endif 4592 CVT_NONE}, 4593 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4594 CVT(JIT_OP_CHECK_INT, int), 4595 CVT_NONE }, 4596 /* from 32-bit float */ 4597 { CVT(JIT_OP_FLOAT32_TO_INT, int), 4598 CVT_NONE, 4599 CVT_NONE }, 4600 { CVT(JIT_OP_CHECK_FLOAT32_TO_INT, int), 4601 CVT_NONE, 4602 CVT_NONE }, 4603 /* from 64-bit float */ 4604 { CVT(JIT_OP_FLOAT64_TO_INT, int), 4605 CVT_NONE, 4606 CVT_NONE }, 4607 { CVT(JIT_OP_CHECK_FLOAT64_TO_INT, int), 4608 CVT_NONE, 4609 CVT_NONE }, 4610 /* from native float */ 4611 { CVT(JIT_OP_NFLOAT_TO_INT, int), 4612 CVT_NONE, 4613 CVT_NONE }, 4614 { CVT(JIT_OP_CHECK_NFLOAT_TO_INT, int), 4615 CVT_NONE, 4616 CVT_NONE } 4617 }; 4618 opcode_map = to_int; 4619 break; 4620 } 4621 4622 case JIT_TYPE_UINT: 4623 { 4624 /* Convert the value into an unsigned int */ 4625 static jit_convert_info_t const to_uint[] = { 4626 /* from signed byte */ 4627 /* from signed short */ 4628 /* from signed int */ 4629 #ifndef JIT_NATIVE_INT32 4630 { CVT(JIT_OP_TRUNC_UINT, uint), 4631 CVT_NONE, 4632 CVT_NONE }, 4633 #else 4634 { CVT(JIT_OP_COPY_INT, uint), 4635 CVT_NONE, 4636 CVT_NONE }, 4637 #endif 4638 { CVT(JIT_OP_CHECK_UINT, uint), 4639 CVT_NONE, 4640 CVT_NONE }, 4641 /* from unsigned byte */ 4642 /* from unsigned short */ 4643 /* from unsigned int */ 4644 { CVT(JIT_OP_COPY_INT, uint), 4645 CVT_NONE, 4646 CVT_NONE }, 4647 { CVT(JIT_OP_COPY_INT, uint), 4648 CVT_NONE, 4649 CVT_NONE }, 4650 /* from signed long */ 4651 { CVT(JIT_OP_LOW_WORD, uint), 4652 CVT_NONE, 4653 CVT_NONE }, 4654 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4655 CVT_NONE, 4656 CVT_NONE }, 4657 /* from unsigned long */ 4658 { CVT(JIT_OP_LOW_WORD, uint), 4659 CVT_NONE, 4660 CVT_NONE }, 4661 { CVT(JIT_OP_CHECK_LOW_WORD, uint), 4662 CVT_NONE, 4663 CVT_NONE }, 4664 /* from 32-bit float */ 4665 { CVT(JIT_OP_FLOAT32_TO_UINT, uint), 4666 CVT_NONE, 4667 CVT_NONE }, 4668 { CVT(JIT_OP_CHECK_FLOAT32_TO_UINT, uint), 4669 CVT_NONE, 4670 CVT_NONE }, 4671 /* from 64-bit float */ 4672 { CVT(JIT_OP_FLOAT64_TO_UINT, uint), 4673 CVT_NONE, 4674 CVT_NONE }, 4675 { CVT(JIT_OP_CHECK_FLOAT64_TO_UINT, uint), 4676 CVT_NONE, 4677 CVT_NONE }, 4678 /* from native float */ 4679 { CVT(JIT_OP_NFLOAT_TO_UINT, uint), 4680 CVT_NONE, 4681 CVT_NONE }, 4682 { CVT(JIT_OP_CHECK_NFLOAT_TO_UINT, uint), 4683 CVT_NONE, 4684 CVT_NONE } 4685 }; 4686 opcode_map = to_uint; 4687 break; 4688 } 4689 4690 case JIT_TYPE_LONG: 4691 { 4692 /* Convert the value into a signed long */ 4693 static jit_convert_info_t const to_long[] = { 4694 /* from signed byte */ 4695 /* from signed short */ 4696 /* from signed int */ 4697 { CVT(JIT_OP_EXPAND_INT, long), 4698 CVT_NONE, 4699 CVT_NONE }, 4700 { CVT(JIT_OP_EXPAND_INT, long), 4701 CVT_NONE, 4702 CVT_NONE }, 4703 /* from unsigned byte */ 4704 /* from unsigned short */ 4705 /* from unsigned int */ 4706 { CVT(JIT_OP_EXPAND_UINT, long), 4707 CVT_NONE, 4708 CVT_NONE }, 4709 { CVT(JIT_OP_EXPAND_UINT, long), 4710 CVT_NONE, 4711 CVT_NONE }, 4712 /* from signed long */ 4713 { CVT(JIT_OP_COPY_LONG, long), 4714 CVT_NONE, 4715 CVT_NONE }, 4716 { CVT(JIT_OP_COPY_LONG, long), 4717 CVT_NONE, 4718 CVT_NONE }, 4719 /* from unsigned long */ 4720 { CVT(JIT_OP_COPY_LONG, long), 4721 CVT_NONE, 4722 CVT_NONE }, 4723 { CVT(JIT_OP_CHECK_LONG, long), 4724 CVT_NONE, 4725 CVT_NONE }, 4726 /* from 32-bit float */ 4727 { CVT(JIT_OP_FLOAT32_TO_LONG, long), 4728 CVT_NONE, 4729 CVT_NONE }, 4730 { CVT(JIT_OP_CHECK_FLOAT32_TO_LONG, long), 4731 CVT_NONE, 4732 CVT_NONE }, 4733 /* from 64-bit float */ 4734 { CVT(JIT_OP_FLOAT64_TO_LONG, long), 4735 CVT_NONE, 4736 CVT_NONE }, 4737 { CVT(JIT_OP_CHECK_FLOAT64_TO_LONG, long), 4738 CVT_NONE, 4739 CVT_NONE }, 4740 /* from native float */ 4741 { CVT(JIT_OP_NFLOAT_TO_LONG, long), 4742 CVT_NONE, 4743 CVT_NONE }, 4744 { CVT(JIT_OP_CHECK_NFLOAT_TO_LONG, long), 4745 CVT_NONE, 4746 CVT_NONE } 4747 }; 4748 opcode_map = to_long; 4749 break; 4750 } 4751 4752 case JIT_TYPE_ULONG: 4753 { 4754 /* Convert the value into an unsigned long */ 4755 static jit_convert_info_t const to_ulong[] = { 4756 /* from signed byte */ 4757 /* from signed short */ 4758 /* from signed int */ 4759 { CVT(JIT_OP_EXPAND_INT, ulong), 4760 CVT_NONE, 4761 CVT_NONE }, 4762 { CVT(JIT_OP_CHECK_UINT, uint), 4763 CVT(JIT_OP_EXPAND_UINT, ulong), 4764 CVT_NONE }, 4765 /* from unsigned byte */ 4766 /* from unsigned short */ 4767 /* from unsigned int */ 4768 { CVT(JIT_OP_EXPAND_UINT, ulong), 4769 CVT_NONE, 4770 CVT_NONE }, 4771 { CVT(JIT_OP_EXPAND_UINT, ulong), 4772 CVT_NONE, 4773 CVT_NONE }, 4774 /* from signed long */ 4775 { CVT(JIT_OP_COPY_LONG, ulong), 4776 CVT_NONE, 4777 CVT_NONE }, 4778 { CVT(JIT_OP_CHECK_ULONG, ulong), 4779 CVT_NONE, 4780 CVT_NONE }, 4781 /* from unsigned long */ 4782 { CVT(JIT_OP_COPY_LONG, ulong), 4783 CVT_NONE, 4784 CVT_NONE }, 4785 { CVT(JIT_OP_COPY_LONG, ulong), 4786 CVT_NONE, 4787 CVT_NONE }, 4788 /* from 32-bit float */ 4789 { CVT(JIT_OP_FLOAT32_TO_ULONG, ulong), 4790 CVT_NONE, 4791 CVT_NONE }, 4792 { CVT(JIT_OP_CHECK_FLOAT32_TO_ULONG, ulong), 4793 CVT_NONE, 4794 CVT_NONE }, 4795 /* from 64-bit float */ 4796 { CVT(JIT_OP_FLOAT64_TO_ULONG, ulong), 4797 CVT_NONE, 4798 CVT_NONE }, 4799 { CVT(JIT_OP_CHECK_FLOAT64_TO_ULONG, ulong), 4800 CVT_NONE, 4801 CVT_NONE }, 4802 /* from native float */ 4803 { CVT(JIT_OP_NFLOAT_TO_ULONG, ulong), 4804 CVT_NONE, 4805 CVT_NONE }, 4806 { CVT(JIT_OP_CHECK_NFLOAT_TO_ULONG, ulong), 4807 CVT_NONE, 4808 CVT_NONE } 4809 }; 4810 opcode_map = to_ulong; 4811 break; 4812 } 4813 4814 case JIT_TYPE_FLOAT32: 4815 { 4816 /* Convert the value into a 32-bit float */ 4817 static jit_convert_info_t const to_float32[] = { 4818 /* from signed byte */ 4819 /* from signed short */ 4820 /* from signed int */ 4821 { CVT(JIT_OP_INT_TO_FLOAT32, float32), 4822 CVT_NONE, 4823 CVT_NONE }, 4824 { CVT(JIT_OP_INT_TO_FLOAT32, float32), 4825 CVT_NONE, 4826 CVT_NONE }, 4827 /* from unsigned byte */ 4828 /* from unsigned short */ 4829 /* from unsigned int */ 4830 { CVT(JIT_OP_UINT_TO_FLOAT32, float32), 4831 CVT_NONE, 4832 CVT_NONE }, 4833 { CVT(JIT_OP_UINT_TO_FLOAT32, float32), 4834 CVT_NONE, 4835 CVT_NONE }, 4836 /* from signed long */ 4837 { CVT(JIT_OP_LONG_TO_FLOAT32, float32), 4838 CVT_NONE, 4839 CVT_NONE }, 4840 { CVT(JIT_OP_LONG_TO_FLOAT32, float32), 4841 CVT_NONE, 4842 CVT_NONE }, 4843 /* from unsigned long */ 4844 { CVT(JIT_OP_ULONG_TO_FLOAT32, float32), 4845 CVT_NONE, 4846 CVT_NONE }, 4847 { CVT(JIT_OP_ULONG_TO_FLOAT32, float32), 4848 CVT_NONE, 4849 CVT_NONE }, 4850 /* from 32-bit float */ 4851 { CVT(JIT_OP_COPY_FLOAT32, float32), 4852 CVT_NONE, 4853 CVT_NONE }, 4854 { CVT(JIT_OP_COPY_FLOAT32, float32), 4855 CVT_NONE, 4856 CVT_NONE }, 4857 /* from 64-bit float */ 4858 { CVT(JIT_OP_FLOAT64_TO_FLOAT32, float32), 4859 CVT_NONE, 4860 CVT_NONE }, 4861 { CVT(JIT_OP_FLOAT64_TO_FLOAT32, float32), 4862 CVT_NONE, 4863 CVT_NONE }, 4864 /* from native float */ 4865 { CVT(JIT_OP_NFLOAT_TO_FLOAT32, float32), 4866 CVT_NONE, 4867 CVT_NONE }, 4868 { CVT(JIT_OP_NFLOAT_TO_FLOAT32, float32), 4869 CVT_NONE, 4870 CVT_NONE } 4871 }; 4872 opcode_map = to_float32; 4873 break; 4874 } 4875 4876 case JIT_TYPE_FLOAT64: 4877 { 4878 /* Convert the value into a 64-bit float */ 4879 static jit_convert_info_t const to_float64[] = { 4880 /* from signed byte */ 4881 /* from signed short */ 4882 /* from signed int */ 4883 { CVT(JIT_OP_INT_TO_FLOAT64, float64), 4884 CVT_NONE, 4885 CVT_NONE }, 4886 { CVT(JIT_OP_INT_TO_FLOAT64, float64), 4887 CVT_NONE, 4888 CVT_NONE }, 4889 /* from unsigned byte */ 4890 /* from unsigned short */ 4891 /* from unsigned int */ 4892 { CVT(JIT_OP_UINT_TO_FLOAT64, float64), 4893 CVT_NONE, 4894 CVT_NONE }, 4895 { CVT(JIT_OP_UINT_TO_FLOAT64, float64), 4896 CVT_NONE, 4897 CVT_NONE }, 4898 /* from signed long */ 4899 { CVT(JIT_OP_LONG_TO_FLOAT64, float64), 4900 CVT_NONE, 4901 CVT_NONE }, 4902 { CVT(JIT_OP_LONG_TO_FLOAT64, float64), 4903 CVT_NONE, 4904 CVT_NONE }, 4905 /* from unsigned long */ 4906 { CVT(JIT_OP_ULONG_TO_FLOAT64, float64), 4907 CVT_NONE, 4908 CVT_NONE }, 4909 { CVT(JIT_OP_ULONG_TO_FLOAT64, float64), 4910 CVT_NONE, 4911 CVT_NONE }, 4912 /* from 32-bit float */ 4913 { CVT(JIT_OP_FLOAT32_TO_FLOAT64, float64), 4914 CVT_NONE, 4915 CVT_NONE }, 4916 { CVT(JIT_OP_FLOAT32_TO_FLOAT64, float64), 4917 CVT_NONE, 4918 CVT_NONE }, 4919 /* from 64-bit float */ 4920 { CVT(JIT_OP_COPY_FLOAT64, float64), 4921 CVT_NONE, 4922 CVT_NONE }, 4923 { CVT(JIT_OP_COPY_FLOAT64, float64), 4924 CVT_NONE, 4925 CVT_NONE }, 4926 /* from native float */ 4927 { CVT(JIT_OP_NFLOAT_TO_FLOAT64, float64), 4928 CVT_NONE, 4929 CVT_NONE }, 4930 { CVT(JIT_OP_NFLOAT_TO_FLOAT64, float64), 4931 CVT_NONE, 4932 CVT_NONE } 4933 }; 4934 opcode_map = to_float64; 4935 break; 4936 } 4937 4938 case JIT_TYPE_NFLOAT: 4939 { 4940 /* Convert the value into a native floating-point value */ 4941 static jit_convert_info_t const to_nfloat[] = { 4942 /* from signed byte */ 4943 /* from signed short */ 4944 /* from signed int */ 4945 { CVT(JIT_OP_INT_TO_NFLOAT, nfloat), 4946 CVT_NONE, 4947 CVT_NONE }, 4948 { CVT(JIT_OP_INT_TO_NFLOAT, nfloat), 4949 CVT_NONE, 4950 CVT_NONE }, 4951 /* from unsigned byte */ 4952 /* from unsigned short */ 4953 /* from unsigned int */ 4954 { CVT(JIT_OP_UINT_TO_NFLOAT, nfloat), 4955 CVT_NONE, 4956 CVT_NONE }, 4957 { CVT(JIT_OP_UINT_TO_NFLOAT, nfloat), 4958 CVT_NONE, 4959 CVT_NONE }, 4960 /* from signed long */ 4961 { CVT(JIT_OP_LONG_TO_NFLOAT, nfloat), 4962 CVT_NONE, 4963 CVT_NONE }, 4964 { CVT(JIT_OP_LONG_TO_NFLOAT, nfloat), 4965 CVT_NONE, 4966 CVT_NONE }, 4967 /* from unsigned long */ 4968 { CVT(JIT_OP_ULONG_TO_NFLOAT, nfloat), 4969 CVT_NONE, 4970 CVT_NONE }, 4971 { CVT(JIT_OP_ULONG_TO_NFLOAT, nfloat), 4972 CVT_NONE, 4973 CVT_NONE }, 4974 /* from 32-bit float */ 4975 { CVT(JIT_OP_FLOAT32_TO_NFLOAT, nfloat), 4976 CVT_NONE, 4977 CVT_NONE }, 4978 { CVT(JIT_OP_FLOAT32_TO_NFLOAT, nfloat), 4979 CVT_NONE, 4980 CVT_NONE }, 4981 /* from 64-bit float */ 4982 { CVT(JIT_OP_FLOAT64_TO_NFLOAT, nfloat), 4983 CVT_NONE, 4984 CVT_NONE }, 4985 { CVT(JIT_OP_FLOAT64_TO_NFLOAT, nfloat), 4986 CVT_NONE, 4987 CVT_NONE }, 4988 /* from native float */ 4989 { CVT(JIT_OP_COPY_NFLOAT, nfloat), 4990 CVT_NONE, 4991 CVT_NONE }, 4992 { CVT(JIT_OP_COPY_NFLOAT, nfloat), 4993 CVT_NONE, 4994 CVT_NONE } 4995 }; 4996 opcode_map = to_nfloat; 4997 break; 4998 } 4999 } 5000 5001 if(opcode_map) 5002 { 5003 switch(vtype->kind) 5004 { 5005 case JIT_TYPE_UINT: opcode_map += 2; break; 5006 case JIT_TYPE_LONG: opcode_map += 4; break; 5007 case JIT_TYPE_ULONG: opcode_map += 6; break; 5008 case JIT_TYPE_FLOAT32: opcode_map += 8; break; 5009 case JIT_TYPE_FLOAT64: opcode_map += 10; break; 5010 case JIT_TYPE_NFLOAT: opcode_map += 12; break; 5011 } 5012 if(overflow_check) 5013 { 5014 opcode_map += 1; 5015 } 5016 if(opcode_map->cvt1) 5017 { 5018 value = apply_conversion(func, opcode_map->cvt1, value, 5019 opcode_map->type1); 5020 } 5021 if(opcode_map->cvt2 && value) 5022 { 5023 value = apply_conversion(func, opcode_map->cvt2, value, 5024 opcode_map->type2); 5025 } 5026 if(opcode_map->cvt3 && value) 5027 { 5028 value = apply_conversion(func, opcode_map->cvt3, value, 5029 opcode_map->type3); 5030 } 5031 } 5032 return value; 5033 } 5034 5035 /* 5036 * Convert the parameters for a function call into their final types. 5037 */ 5038 static int 5039 convert_call_parameters(jit_function_t func, jit_type_t signature, 5040 jit_value_t *args, unsigned int num_args, 5041 jit_value_t *new_args) 5042 { 5043 unsigned int param; 5044 for(param = 0; param < num_args; ++param) 5045 { 5046 new_args[param] = jit_insn_convert(func, args[param], 5047 jit_type_get_param(signature, param), 5048 0); 5049 if (!new_args[param]) 5050 return 0; 5051 } 5052 return 1; 5053 } 5054 5055 /* 5056 * Set up the exception frame information before a function call out. 5057 */ 5058 static int 5059 setup_eh_frame_for_call(jit_function_t func, int flags) 5060 { 5061 #if !defined(JIT_BACKEND_INTERP) 5062 jit_type_t type; 5063 jit_value_t args[2]; 5064 jit_insn_t insn; 5065 5066 /* If "tail" is set, then we need to pop the "setjmp" context */ 5067 if((flags & JIT_CALL_TAIL) != 0 && func->has_try) 5068 { 5069 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 1); 5070 if(!type) 5071 { 5072 return 0; 5073 } 5074 jit_insn_call_native(func, "_jit_unwind_pop_setjmp", 5075 (void *) _jit_unwind_pop_setjmp, type, 5076 0, 0, JIT_CALL_NOTHROW); 5077 jit_type_free(type); 5078 } 5079 5080 /* If "nothrow" or "tail" is set, then there is no more to do */ 5081 if((flags & (JIT_CALL_NOTHROW | JIT_CALL_TAIL)) != 0) 5082 { 5083 return 1; 5084 } 5085 5086 /* This function may throw an exception */ 5087 func->builder->may_throw = 1; 5088 5089 #if JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 5090 { 5091 jit_value_t eh_frame_info; 5092 jit_type_t params[2]; 5093 5094 /* Get the value that holds the exception frame information */ 5095 if((eh_frame_info = func->builder->eh_frame_info) == 0) 5096 { 5097 type = jit_type_create_struct(0, 0, 0); 5098 if(!type) 5099 { 5100 return 0; 5101 } 5102 jit_type_set_size_and_alignment(type, 5103 sizeof(struct jit_backtrace), 5104 sizeof(void *)); 5105 eh_frame_info = jit_value_create(func, type); 5106 jit_type_free(type); 5107 if(!eh_frame_info) 5108 { 5109 return 0; 5110 } 5111 func->builder->eh_frame_info = eh_frame_info; 5112 } 5113 5114 /* Output an instruction to load the "pc" into a value */ 5115 args[1] = jit_value_create(func, jit_type_void_ptr); 5116 if(!args[1]) 5117 { 5118 return 0; 5119 } 5120 insn = _jit_block_add_insn(func->builder->current_block); 5121 if(!insn) 5122 { 5123 return 0; 5124 } 5125 insn->opcode = JIT_OP_LOAD_PC; 5126 insn->dest = args[1]; 5127 5128 /* Load the address of "eh_frame_info" into another value */ 5129 args[0] = jit_insn_address_of(func, eh_frame_info); 5130 if(!args[0]) 5131 { 5132 return 0; 5133 } 5134 5135 /* Create a signature for the prototype "void (void *, void *)" */ 5136 params[0] = jit_type_void_ptr; 5137 params[1] = jit_type_void_ptr; 5138 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 2, 1); 5139 if(!type) 5140 { 5141 return 0; 5142 } 5143 5144 /* Call the "_jit_backtrace_push" function */ 5145 jit_insn_call_native(func, "_jit_backtrace_push", 5146 (void *) _jit_backtrace_push, type, 5147 args, 2, JIT_CALL_NOTHROW); 5148 jit_type_free(type); 5149 } 5150 #endif 5151 5152 /* Update the "catch_pc" value to reflect the current context */ 5153 if(func->builder->setjmp_value != 0) 5154 { 5155 args[0] = jit_value_create(func, jit_type_void_ptr); 5156 if(!args[0]) 5157 { 5158 return 0; 5159 } 5160 5161 insn = _jit_block_add_insn(func->builder->current_block); 5162 if(!insn) 5163 { 5164 return 0; 5165 } 5166 insn->opcode = JIT_OP_LOAD_PC; 5167 insn->dest = args[0]; 5168 5169 jit_value_t addr = jit_insn_address_of(func, func->builder->setjmp_value); 5170 if(!addr) 5171 { 5172 return 0; 5173 } 5174 if(!jit_insn_store_relative(func, addr, jit_jmp_catch_pc_offset, args[0])) 5175 { 5176 return 0; 5177 } 5178 } 5179 5180 /* We are now ready to make the actual function call */ 5181 return 1; 5182 #else /* JIT_BACKEND_INTERP */ 5183 /* The interpreter handles exception frames for us */ 5184 if((flags & (JIT_CALL_NOTHROW | JIT_CALL_TAIL)) == 0) 5185 { 5186 func->builder->may_throw = 1; 5187 } 5188 return 1; 5189 #endif 5190 } 5191 5192 /* 5193 * Restore the exception handling frame after a function call. 5194 */ 5195 static int 5196 restore_eh_frame_after_call(jit_function_t func, int flags) 5197 { 5198 #if !defined(JIT_BACKEND_INTERP) 5199 /* If the "nothrow", "noreturn", or "tail" flags are set, then we 5200 don't need to worry about this */ 5201 if((flags & (JIT_CALL_NOTHROW | JIT_CALL_NORETURN | JIT_CALL_TAIL)) != 0) 5202 { 5203 return 1; 5204 } 5205 5206 #if JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 5207 /* Create the signature prototype "void (void)" */ 5208 jit_type_t type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 0); 5209 if(!type) 5210 { 5211 return 0; 5212 } 5213 5214 /* Call the "_jit_backtrace_pop" function */ 5215 jit_insn_call_native(func, "_jit_backtrace_pop", 5216 (void *) _jit_backtrace_pop, type, 5217 0, 0, JIT_CALL_NOTHROW); 5218 jit_type_free(type); 5219 #endif 5220 5221 /* Clear the "catch_pc" value for the current context */ 5222 if(func->builder->setjmp_value != 0) 5223 { 5224 jit_value_t null = jit_value_create_nint_constant(func, jit_type_void_ptr, 0); 5225 jit_value_t addr = jit_insn_address_of(func, func->builder->setjmp_value); 5226 if(!null || !addr) 5227 { 5228 return 0; 5229 } 5230 if(!jit_insn_store_relative(func, addr, jit_jmp_catch_pc_offset, null)) 5231 { 5232 return 0; 5233 } 5234 } 5235 5236 /* Everything is back to where it should be */ 5237 return 1; 5238 #else /* JIT_BACKEND_INTERP */ 5239 /* The interpreter handles exception frames for us */ 5240 return 1; 5241 #endif 5242 } 5243 5244 /* 5245 * Determine if two signatures are identical for the purpose of tail calls. 5246 */ 5247 static int 5248 signature_identical(jit_type_t type1, jit_type_t type2) 5249 { 5250 /* Handle the easy case first */ 5251 if(type1 == type2) 5252 { 5253 return 1; 5254 } 5255 5256 /* Remove the tags and then bail out if either type is invalid */ 5257 type1 = jit_type_remove_tags(type1); 5258 type2 = jit_type_remove_tags(type2); 5259 if(!type1 || !type2) 5260 { 5261 return 0; 5262 } 5263 5264 /* Normalize pointer types, but leave signature types as-is */ 5265 if(type1->kind == JIT_TYPE_PTR) 5266 { 5267 type1 = jit_type_normalize(type1); 5268 } 5269 if(type2->kind == JIT_TYPE_PTR) 5270 { 5271 type2 = jit_type_normalize(type2); 5272 } 5273 5274 #ifdef JIT_NFLOAT_IS_DOUBLE 5275 /* "double" and "nfloat" are identical on this platform */ 5276 if((type1->kind == JIT_TYPE_FLOAT64 || type1->kind == JIT_TYPE_NFLOAT) && 5277 (type2->kind == JIT_TYPE_FLOAT64 || type2->kind == JIT_TYPE_NFLOAT)) 5278 { 5279 return 1; 5280 } 5281 #endif 5282 5283 /* If the kinds are not the same now, then we don't have a match */ 5284 if(type1->kind != type2->kind) 5285 { 5286 return 0; 5287 } 5288 5289 /* Structure and union types must have the same size and alignment */ 5290 if(type1->kind == JIT_TYPE_STRUCT || type1->kind == JIT_TYPE_UNION) 5291 { 5292 return (jit_type_get_size(type1) == jit_type_get_size(type2) && 5293 jit_type_get_alignment(type1) == jit_type_get_alignment(type2)); 5294 } 5295 5296 /* Signature types must be compared component-by-component */ 5297 if(type1->kind == JIT_TYPE_SIGNATURE) 5298 { 5299 if(type1->abi != type2->abi) 5300 { 5301 return 0; 5302 } 5303 if(!signature_identical(type1->sub_type, type2->sub_type)) 5304 { 5305 return 0; 5306 } 5307 if(type1->num_components != type2->num_components) 5308 { 5309 return 0; 5310 } 5311 5312 unsigned int param; 5313 for(param = 0; param < type1->num_components; ++param) 5314 { 5315 if(!signature_identical(type1->components[param].type, 5316 type2->components[param].type)) 5317 { 5318 return 0; 5319 } 5320 } 5321 } 5322 5323 /* If we get here, then the types are compatible */ 5324 return 1; 5325 } 5326 5327 /* 5328 * Create call setup instructions, taking tail calls into effect. 5329 */ 5330 static int 5331 create_call_setup_insns(jit_function_t func, jit_function_t callee, 5332 jit_type_t signature, 5333 jit_value_t *args, unsigned int num_args, 5334 int is_nested, jit_value_t parent_frame, 5335 jit_value_t *struct_return, int flags) 5336 { 5337 jit_value_t *new_args; 5338 unsigned int arg_num; 5339 5340 /* If we are performing a tail call, then duplicate the argument 5341 values so that we don't accidentally destroy parameters in 5342 situations like func(x, y) -> func(y, x) */ 5343 if((flags & JIT_CALL_TAIL) != 0 && num_args > 0) 5344 { 5345 new_args = (jit_value_t *) alloca(sizeof(jit_value_t) * num_args); 5346 for(arg_num = 0; arg_num < num_args; ++arg_num) 5347 { 5348 jit_value_t value = args[arg_num]; 5349 if(value && value->is_parameter) 5350 { 5351 value = jit_insn_dup(func, value); 5352 if(!value) 5353 { 5354 return 0; 5355 } 5356 } 5357 new_args[arg_num] = value; 5358 } 5359 args = new_args; 5360 } 5361 5362 /* If we are performing a tail call, then store back to our own parameters */ 5363 if((flags & JIT_CALL_TAIL) != 0) 5364 { 5365 for(arg_num = 0; arg_num < num_args; ++arg_num) 5366 { 5367 if(!jit_insn_store(func, jit_value_get_param(func, arg_num), 5368 args[arg_num])) 5369 { 5370 return 0; 5371 } 5372 } 5373 *struct_return = 0; 5374 return 1; 5375 } 5376 5377 /* Let the back end do the work */ 5378 return _jit_create_call_setup_insns(func, signature, args, num_args, 5379 is_nested, parent_frame, struct_return, 5380 flags); 5381 } 5382 5383 static jit_value_t 5384 handle_return(jit_function_t func, 5385 jit_type_t signature, 5386 int flags, int is_nested, 5387 jit_value_t *args, unsigned int num_args, 5388 jit_value_t return_value) 5389 { 5390 /* If the function does not return, then end the current block. 5391 The next block does not have "entered_via_top" set so that 5392 it will be eliminated during later code generation */ 5393 if((flags & (JIT_CALL_NORETURN | JIT_CALL_TAIL)) != 0) 5394 { 5395 func->builder->current_block->ends_in_dead = 1; 5396 } 5397 5398 /* If the function may throw an exceptions then end the current 5399 basic block to account for exceptional control flow */ 5400 if((flags & JIT_CALL_NOTHROW) == 0) 5401 { 5402 if(!jit_insn_new_block(func)) 5403 { 5404 return 0; 5405 } 5406 } 5407 5408 /* Create space for the return value, if we don't already have one */ 5409 if(!return_value) 5410 { 5411 return_value = jit_value_create(func, jit_type_get_return(signature)); 5412 if(!return_value) 5413 { 5414 return 0; 5415 } 5416 } 5417 5418 /* Create the instructions necessary to move the return value into place */ 5419 if((flags & JIT_CALL_TAIL) == 0) 5420 { 5421 if(!_jit_create_call_return_insns(func, signature, args, num_args, 5422 return_value, is_nested)) 5423 { 5424 return 0; 5425 } 5426 } 5427 5428 /* Restore exception frame information after the call */ 5429 if(!restore_eh_frame_after_call(func, flags)) 5430 { 5431 return 0; 5432 } 5433 5434 /* Return the value containing the result to the caller */ 5435 return return_value; 5436 } 5437 5438 /*@ 5439 * @deftypefun jit_value_t jit_insn_call (jit_function_t @var{func}, const char *@var{name}, jit_function_t @var{jit_func}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 5440 * Call the function @var{jit_func}, which may or may not be translated yet. 5441 * The @var{name} is for diagnostic purposes only, and can be NULL. 5442 * 5443 * If @var{signature} is NULL, then the actual signature of @var{jit_func} 5444 * is used in its place. This is the usual case. However, if the function 5445 * takes a variable number of arguments, then you may need to construct 5446 * an explicit signature for the non-fixed argument values. 5447 * 5448 * The @var{flags} parameter specifies additional information about the 5449 * type of call to perform: 5450 * 5451 * @table @code 5452 * @vindex JIT_CALL_NOTHROW 5453 * @item JIT_CALL_NOTHROW 5454 * The function never throws exceptions. 5455 * 5456 * @vindex JIT_CALL_NORETURN 5457 * @item JIT_CALL_NORETURN 5458 * The function will never return directly to its caller. It may however 5459 * return to the caller indirectly by throwing an exception that the 5460 * caller catches. 5461 * 5462 * @vindex JIT_CALL_TAIL 5463 * @item JIT_CALL_TAIL 5464 * Apply tail call optimizations, as the result of this function 5465 * call will be immediately returned from the containing function. 5466 * Tail calls are only appropriate when the signature of the called 5467 * function matches the callee, and none of the parameters point 5468 * to local variables. 5469 * @end table 5470 * 5471 * If @var{jit_func} has already been compiled, then @code{jit_insn_call} 5472 * may be able to intuit some of the above flags for itself. Otherwise 5473 * it is up to the caller to determine when the flags may be appropriate. 5474 * @end deftypefun 5475 @*/ 5476 jit_value_t 5477 jit_insn_call(jit_function_t func, const char *name, jit_function_t jit_func, 5478 jit_type_t signature, jit_value_t *args, unsigned int num_args, 5479 int flags) 5480 { 5481 int is_nested; 5482 jit_value_t parent_frame; 5483 jit_value_t return_value; 5484 jit_label_t entry_point; 5485 jit_label_t label_end; 5486 5487 /* Ensure that we have a function builder */ 5488 if(!_jit_function_ensure_builder(func)) 5489 { 5490 return 0; 5491 } 5492 5493 /* Get the default signature from "jit_func" */ 5494 if(!signature) 5495 { 5496 signature = jit_func->signature; 5497 } 5498 5499 /* Verify that tail calls are possible to the destination */ 5500 if((flags & JIT_CALL_TAIL) != 0) 5501 { 5502 if(func->nested_parent || jit_func->nested_parent) 5503 { 5504 /* Cannot use tail calls with nested function calls */ 5505 flags &= ~JIT_CALL_TAIL; 5506 } 5507 else if(!signature_identical(signature, func->signature)) 5508 { 5509 /* The signatures are not the same, so tail calls not allowed */ 5510 flags &= ~JIT_CALL_TAIL; 5511 } 5512 } 5513 5514 /* Determine the nesting relationship with the current function */ 5515 if(jit_func->nested_parent) 5516 { 5517 is_nested = 1; 5518 parent_frame = jit_insn_get_parent_frame_pointer_of(func, jit_func); 5519 5520 if(!parent_frame) 5521 { 5522 return 0; 5523 } 5524 } 5525 else 5526 { 5527 is_nested = 0; 5528 parent_frame = 0; 5529 } 5530 5531 /* Convert the arguments to the actual parameter types */ 5532 jit_value_t *new_args; 5533 if(num_args > 0) 5534 { 5535 new_args = (jit_value_t *) alloca(sizeof(jit_value_t) * num_args); 5536 if(!convert_call_parameters(func, signature, args, num_args, new_args)) 5537 { 5538 return 0; 5539 } 5540 } 5541 else 5542 { 5543 new_args = args; 5544 } 5545 5546 /* Intuit additional flags from "jit_func" if it was already compiled */ 5547 if(jit_func->no_throw) 5548 { 5549 flags |= JIT_CALL_NOTHROW; 5550 } 5551 if(jit_func->no_return) 5552 { 5553 flags |= JIT_CALL_NORETURN; 5554 } 5555 5556 /* Set up exception frame information for the call */ 5557 if(!setup_eh_frame_for_call(func, flags)) 5558 { 5559 return 0; 5560 } 5561 5562 /* Create the instructions to push the parameters onto the stack */ 5563 if(!create_call_setup_insns(func, jit_func, signature, new_args, num_args, 5564 is_nested, parent_frame, &return_value, flags)) 5565 { 5566 return 0; 5567 } 5568 5569 /* Output the "call" instruction */ 5570 if((flags & JIT_CALL_TAIL) != 0 && func == jit_func) 5571 { 5572 /* We are performing a tail call to ourselves, which we can 5573 turn into an unconditional branch back to our entry point */ 5574 entry_point = jit_label_undefined; 5575 label_end = jit_label_undefined; 5576 if(!jit_insn_branch(func, &entry_point)) 5577 { 5578 return 0; 5579 } 5580 if(!jit_insn_label_tight(func, &entry_point)) 5581 { 5582 return 0; 5583 } 5584 if(!jit_insn_label(func, &label_end)) 5585 { 5586 return 0; 5587 } 5588 if(!jit_insn_move_blocks_to_start(func, entry_point, label_end)) 5589 { 5590 return 0; 5591 } 5592 } 5593 else 5594 { 5595 /* Functions that call out are not leaves */ 5596 func->builder->non_leaf = 1; 5597 5598 /* Performing a regular call, or a tail call to someone else */ 5599 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 5600 if(!insn) 5601 { 5602 return 0; 5603 } 5604 if((flags & JIT_CALL_TAIL) != 0) 5605 { 5606 func->builder->has_tail_call = 1; 5607 insn->opcode = JIT_OP_CALL_TAIL; 5608 } 5609 else 5610 { 5611 insn->opcode = JIT_OP_CALL; 5612 } 5613 insn->flags = JIT_INSN_DEST_IS_FUNCTION | JIT_INSN_VALUE1_IS_NAME; 5614 insn->dest = (jit_value_t) jit_func; 5615 insn->value1 = (jit_value_t) name; 5616 } 5617 5618 /* Handle return to the caller */ 5619 return handle_return(func, signature, flags, is_nested, new_args, num_args, return_value); 5620 } 5621 5622 /*@ 5623 * @deftypefun jit_value_t jit_insn_call_indirect (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 5624 * Call a function via an indirect pointer. 5625 * @end deftypefun 5626 @*/ 5627 jit_value_t 5628 jit_insn_call_nested_indirect(jit_function_t func, jit_value_t value, 5629 jit_value_t parent_frame, jit_type_t signature, jit_value_t *args, 5630 unsigned int num_args, int flags) 5631 { 5632 int is_nested = parent_frame ? 1 : 0; 5633 5634 /* Ensure that we have a function builder */ 5635 if(!_jit_function_ensure_builder(func)) 5636 { 5637 return 0; 5638 } 5639 5640 /* Verify that tail calls are possible to the destination */ 5641 #if defined(JIT_BACKEND_INTERP) 5642 flags &= ~JIT_CALL_TAIL; 5643 #else 5644 if((flags & JIT_CALL_TAIL) != 0) 5645 { 5646 if(is_nested || func->nested_parent) 5647 { 5648 flags &= ~JIT_CALL_TAIL; 5649 } 5650 else if(!signature_identical(signature, func->signature)) 5651 { 5652 flags &= ~JIT_CALL_TAIL; 5653 } 5654 } 5655 #endif 5656 5657 /* We are making a native call */ 5658 flags |= JIT_CALL_NATIVE; 5659 5660 /* Convert the arguments to the actual parameter types */ 5661 jit_value_t *new_args; 5662 if(num_args > 0) 5663 { 5664 new_args = (jit_value_t *) alloca(sizeof(jit_value_t) * num_args); 5665 if(!convert_call_parameters(func, signature, args, num_args, new_args)) 5666 { 5667 return 0; 5668 } 5669 } 5670 else 5671 { 5672 new_args = args; 5673 } 5674 5675 /* Set up exception frame information for the call */ 5676 if(!setup_eh_frame_for_call(func, flags)) 5677 { 5678 return 0; 5679 } 5680 5681 /* Create the instructions to push the parameters onto the stack */ 5682 jit_value_t return_value; 5683 if(!create_call_setup_insns(func, 0, signature, new_args, num_args, 5684 is_nested, parent_frame, &return_value, flags)) 5685 { 5686 return 0; 5687 } 5688 5689 /* Move the indirect pointer value into an appropriate register */ 5690 if(!_jit_setup_indirect_pointer(func, value)) 5691 { 5692 return 0; 5693 } 5694 5695 /* Functions that call out are not leaves */ 5696 func->builder->non_leaf = 1; 5697 5698 /* Output the "call_indirect" instruction */ 5699 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 5700 if(!insn) 5701 { 5702 return 0; 5703 } 5704 if((flags & JIT_CALL_TAIL) != 0) 5705 { 5706 func->builder->has_tail_call = 1; 5707 insn->opcode = JIT_OP_CALL_INDIRECT_TAIL; 5708 } 5709 else 5710 { 5711 insn->opcode = JIT_OP_CALL_INDIRECT; 5712 } 5713 insn->flags = JIT_INSN_VALUE2_IS_SIGNATURE; 5714 insn->value1 = value; 5715 jit_value_ref(func, value); 5716 insn->value2 = (jit_value_t) jit_type_copy(signature); 5717 5718 /* Handle return to the caller */ 5719 return handle_return(func, signature, flags, is_nested, new_args, num_args, 5720 return_value); 5721 } 5722 5723 /*@ 5724 * @deftypefun jit_value_t jit_insn_call_nested_indirect (jit_function_t @var{func}, jit_value_t @var{value}, jit_value_t @var{parent_frame}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 5725 * Call a jit function that is nested via an indirect pointer. 5726 * @var{parent_frame} should be a pointer to the frame of the parent of *value. 5727 * @end deftypefun 5728 @*/ 5729 jit_value_t 5730 jit_insn_call_indirect(jit_function_t func, jit_value_t value, 5731 jit_type_t signature, jit_value_t *args, 5732 unsigned int num_args, int flags) 5733 { 5734 return jit_insn_call_nested_indirect(func, value, 0, signature, 5735 args, num_args, flags); 5736 } 5737 5738 /*@ 5739 * @deftypefun jit_value_t jit_insn_call_indirect_vtable (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 5740 * Call a function via an indirect pointer. This version differs from 5741 * @code{jit_insn_call_indirect} in that we assume that @var{value} 5742 * contains a pointer that resulted from calling 5743 * @code{jit_function_to_vtable_pointer}. Indirect vtable pointer 5744 * calls may be more efficient on some platforms than regular indirect calls. 5745 * @end deftypefun 5746 @*/ 5747 jit_value_t 5748 jit_insn_call_indirect_vtable(jit_function_t func, jit_value_t value, jit_type_t signature, 5749 jit_value_t *args, unsigned int num_args, int flags) 5750 { 5751 /* Ensure that we have a function builder */ 5752 if(!_jit_function_ensure_builder(func)) 5753 { 5754 return 0; 5755 } 5756 5757 /* Verify that tail calls are possible to the destination */ 5758 if((flags & JIT_CALL_TAIL) != 0) 5759 { 5760 if(func->nested_parent) 5761 { 5762 flags &= ~JIT_CALL_TAIL; 5763 } 5764 else if(!signature_identical(signature, func->signature)) 5765 { 5766 flags &= ~JIT_CALL_TAIL; 5767 } 5768 } 5769 5770 /* Convert the arguments to the actual parameter types */ 5771 jit_value_t *new_args; 5772 if(num_args > 0) 5773 { 5774 new_args = (jit_value_t *) alloca(sizeof(jit_value_t) * num_args); 5775 if(!convert_call_parameters(func, signature, args, num_args, new_args)) 5776 { 5777 return 0; 5778 } 5779 } 5780 else 5781 { 5782 new_args = args; 5783 } 5784 5785 /* Set up exception frame information for the call */ 5786 if(!setup_eh_frame_for_call(func, flags)) 5787 { 5788 return 0; 5789 } 5790 5791 /* Create the instructions to push the parameters onto the stack */ 5792 jit_value_t return_value; 5793 if(!create_call_setup_insns(func, 0, signature, new_args, num_args, 5794 0, 0, &return_value, flags)) 5795 { 5796 return 0; 5797 } 5798 5799 /* Move the indirect pointer value into an appropriate register */ 5800 if(!_jit_setup_indirect_pointer(func, value)) 5801 { 5802 return 0; 5803 } 5804 5805 /* Functions that call out are not leaves */ 5806 func->builder->non_leaf = 1; 5807 5808 /* Output the "call_vtable_ptr" instruction */ 5809 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 5810 if(!insn) 5811 { 5812 return 0; 5813 } 5814 if((flags & JIT_CALL_TAIL) != 0) 5815 { 5816 func->builder->has_tail_call = 1; 5817 insn->opcode = JIT_OP_CALL_VTABLE_PTR_TAIL; 5818 } 5819 else 5820 { 5821 insn->opcode = JIT_OP_CALL_VTABLE_PTR; 5822 } 5823 insn->value1 = value; 5824 jit_value_ref(func, value); 5825 5826 /* Handle return to the caller */ 5827 return handle_return(func, signature, flags, 0, new_args, num_args, return_value); 5828 } 5829 5830 /*@ 5831 * @deftypefun jit_value_t jit_insn_call_native (jit_function_t @var{func}, const char *@var{name}, void *@var{native_func}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 5832 * Output an instruction that calls an external native function. 5833 * The @var{name} is for diagnostic purposes only, and can be NULL. 5834 * @end deftypefun 5835 @*/ 5836 jit_value_t 5837 jit_insn_call_native(jit_function_t func, const char *name, void *native_func, 5838 jit_type_t signature, jit_value_t *args, unsigned int num_args, int flags) 5839 { 5840 /* Ensure that we have a function builder */ 5841 if(!_jit_function_ensure_builder(func)) 5842 { 5843 return 0; 5844 } 5845 5846 /* Verify that tail calls are possible to the destination */ 5847 #if defined(JIT_BACKEND_INTERP) 5848 flags &= ~JIT_CALL_TAIL; 5849 #else 5850 if((flags & JIT_CALL_TAIL) != 0) 5851 { 5852 if(func->nested_parent) 5853 { 5854 flags &= ~JIT_CALL_TAIL; 5855 } 5856 else if(!signature_identical(signature, func->signature)) 5857 { 5858 flags &= ~JIT_CALL_TAIL; 5859 } 5860 } 5861 #endif 5862 5863 /* We are making a native call */ 5864 flags |= JIT_CALL_NATIVE; 5865 5866 /* Convert the arguments to the actual parameter types */ 5867 jit_value_t *new_args; 5868 if(num_args > 0) 5869 { 5870 new_args = (jit_value_t *) alloca(sizeof(jit_value_t) * num_args); 5871 if(!convert_call_parameters(func, signature, args, num_args, new_args)) 5872 { 5873 return 0; 5874 } 5875 } 5876 else 5877 { 5878 new_args = args; 5879 } 5880 5881 /* Set up exception frame information for the call */ 5882 if(!setup_eh_frame_for_call(func, flags)) 5883 { 5884 return 0; 5885 } 5886 5887 /* Create the instructions to push the parameters onto the stack */ 5888 jit_value_t return_value; 5889 if(!create_call_setup_insns(func, 0, signature, new_args, num_args, 5890 0, 0, &return_value, flags)) 5891 { 5892 return 0; 5893 } 5894 5895 /* Functions that call out are not leaves */ 5896 func->builder->non_leaf = 1; 5897 5898 /* Output the "call_external" instruction */ 5899 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 5900 if(!insn) 5901 { 5902 return 0; 5903 } 5904 if((flags & JIT_CALL_TAIL) != 0) 5905 { 5906 func->builder->has_tail_call = 1; 5907 insn->opcode = JIT_OP_CALL_EXTERNAL_TAIL; 5908 } 5909 else 5910 { 5911 insn->opcode = JIT_OP_CALL_EXTERNAL; 5912 } 5913 insn->flags = JIT_INSN_DEST_IS_NATIVE | JIT_INSN_VALUE1_IS_NAME; 5914 insn->dest = (jit_value_t) native_func; 5915 insn->value1 = (jit_value_t) name; 5916 #ifdef JIT_BACKEND_INTERP 5917 insn->flags |= JIT_INSN_VALUE2_IS_SIGNATURE; 5918 insn->value2 = (jit_value_t) jit_type_copy(signature); 5919 #endif 5920 5921 /* Handle return to the caller */ 5922 return_value = handle_return(func, signature, flags, 0, new_args, num_args, return_value); 5923 5924 /* Make sure that returned byte / short values get zero / sign extended */ 5925 jit_type_t return_type = jit_type_remove_tags(return_value->type); 5926 switch(return_type->kind) 5927 { 5928 case JIT_TYPE_SBYTE: 5929 /* Force sbyte sign extension to int */ 5930 return_value = apply_conversion(func, JIT_OP_TRUNC_SBYTE, return_value, 5931 return_type); 5932 break; 5933 case JIT_TYPE_UBYTE: 5934 /* Force ubyte zero extension to uint */ 5935 return_value = apply_conversion(func, JIT_OP_TRUNC_UBYTE, return_value, 5936 return_type); 5937 break; 5938 case JIT_TYPE_SHORT: 5939 /* Force short sign extension to int */ 5940 return_value = apply_conversion(func, JIT_OP_TRUNC_SHORT, return_value, 5941 return_type); 5942 break; 5943 case JIT_TYPE_USHORT: 5944 /* Force ushort zero extension to uint */ 5945 return_value = apply_conversion(func, JIT_OP_TRUNC_USHORT, return_value, 5946 return_type); 5947 break; 5948 } 5949 5950 /* Return the value containing the result to the caller */ 5951 return return_value; 5952 } 5953 5954 /*@ 5955 * @deftypefun jit_value_t jit_insn_call_intrinsic (jit_function_t @var{func}, const char *@var{name}, void *@var{intrinsic_func}, const jit_intrinsic_descr_t *@var{descriptor}, jit_value_t @var{arg1}, jit_value_t @var{arg2}) 5956 * Output an instruction that calls an intrinsic function. The descriptor 5957 * contains the following fields: 5958 * 5959 * @table @code 5960 * @item return_type 5961 * The type of value that is returned from the intrinsic. 5962 * 5963 * @item ptr_result_type 5964 * This should be NULL for an ordinary intrinsic, or the result type 5965 * if the intrinsic reports exceptions. 5966 * 5967 * @item arg1_type 5968 * The type of the first argument. 5969 * 5970 * @item arg2_type 5971 * The type of the second argument, or NULL for a unary intrinsic. 5972 * @end table 5973 * 5974 * If all of the arguments are constant, then @code{jit_insn_call_intrinsic} 5975 * will call the intrinsic directly to calculate the constant result. 5976 * If the constant computation will result in an exception, then 5977 * code is output to cause the exception at runtime. 5978 * 5979 * The @var{name} is for diagnostic purposes only, and can be NULL. 5980 * @end deftypefun 5981 @*/ 5982 jit_value_t 5983 jit_insn_call_intrinsic(jit_function_t func, const char *name, void *intrinsic_func, 5984 const jit_intrinsic_descr_t *descriptor, jit_value_t arg1, 5985 jit_value_t arg2) 5986 { 5987 jit_type_t signature; 5988 jit_type_t param_types[3]; 5989 jit_value_t param_values[3]; 5990 jit_value_t return_value; 5991 jit_value_t temp_value; 5992 jit_value_t cond_value; 5993 jit_label_t label; 5994 jit_constant_t const1; 5995 jit_constant_t const2; 5996 jit_constant_t return_const; 5997 jit_constant_t temp_const; 5998 void *apply_args[3]; 5999 6000 /* Ensure that we have a builder for this function */ 6001 if(!_jit_function_ensure_builder(func)) 6002 { 6003 return 0; 6004 } 6005 6006 /* Coerce the arguments to the desired types */ 6007 arg1 = jit_insn_convert(func, arg1, descriptor->arg1_type, 0); 6008 if(!arg1) 6009 { 6010 return 0; 6011 } 6012 if(arg2) 6013 { 6014 arg2 = jit_insn_convert(func, arg2, descriptor->arg2_type, 0); 6015 if(!arg2) 6016 { 6017 return 0; 6018 } 6019 } 6020 6021 /* Allocate space for a return value if the intrinsic reports exceptions */ 6022 if(descriptor->ptr_result_type) 6023 { 6024 return_value = jit_value_create(func, descriptor->ptr_result_type); 6025 if(!return_value) 6026 { 6027 return 0; 6028 } 6029 } 6030 else 6031 { 6032 return_value = 0; 6033 } 6034 6035 /* Construct the signature for the intrinsic */ 6036 unsigned int num_params = 0; 6037 if(return_value) 6038 { 6039 /* Pass a pointer to "return_value" as the first argument */ 6040 temp_value = jit_insn_address_of(func, return_value); 6041 if(!temp_value) 6042 { 6043 return 0; 6044 } 6045 param_types[num_params] = jit_value_get_type(temp_value); 6046 param_values[num_params] = temp_value; 6047 ++num_params; 6048 } 6049 param_types[num_params] = jit_value_get_type(arg1); 6050 param_values[num_params] = arg1; 6051 ++num_params; 6052 if(arg2) 6053 { 6054 param_types[num_params] = jit_value_get_type(arg2); 6055 param_values[num_params] = arg2; 6056 ++num_params; 6057 } 6058 signature = jit_type_create_signature(jit_abi_cdecl, descriptor->return_type, 6059 param_types, num_params, 1); 6060 if(!signature) 6061 { 6062 return 0; 6063 } 6064 6065 /* If the arguments are constant, then invoke the intrinsic now */ 6066 if(jit_value_is_constant(arg1) 6067 && (!arg2 || jit_value_is_constant(arg2)) 6068 && !jit_context_get_meta_numeric(func->context, JIT_OPTION_DONT_FOLD)) 6069 { 6070 const1 = jit_value_get_constant(arg1); 6071 const2 = jit_value_get_constant(arg2); 6072 if(return_value) 6073 { 6074 jit_int result; 6075 return_const.type = descriptor->ptr_result_type; 6076 temp_const.un.ptr_value = &return_const.un; 6077 apply_args[0] = &temp_const.un; 6078 apply_args[1] = &const1.un; 6079 apply_args[2] = &const2.un; 6080 jit_apply(signature, intrinsic_func, apply_args, num_params, 6081 &result); 6082 if(result >= 1) 6083 { 6084 /* No exception occurred, so return the constant value */ 6085 jit_type_free(signature); 6086 return jit_value_create_constant(func, &return_const); 6087 } 6088 } 6089 else 6090 { 6091 return_const.type = descriptor->return_type; 6092 apply_args[0] = &const1.un; 6093 apply_args[1] = &const2.un; 6094 jit_apply(signature, intrinsic_func, apply_args, num_params, 6095 &return_const.un); 6096 jit_type_free(signature); 6097 return jit_value_create_constant(func, &return_const); 6098 } 6099 } 6100 6101 /* Call the intrinsic as a native function */ 6102 temp_value = jit_insn_call_native(func, name, intrinsic_func, signature, 6103 param_values, num_params, JIT_CALL_NOTHROW); 6104 if(!temp_value) 6105 { 6106 jit_type_free(signature); 6107 return 0; 6108 } 6109 jit_type_free(signature); 6110 6111 /* If no exceptions to report, then return "temp_value" as the result */ 6112 if(!return_value) 6113 { 6114 return temp_value; 6115 } 6116 6117 /* Determine if an exception was reported */ 6118 cond_value = jit_value_create_nint_constant(func, jit_type_int, 1); 6119 cond_value = jit_insn_ge(func, temp_value, cond_value); 6120 if(!cond_value) 6121 { 6122 return 0; 6123 } 6124 label = jit_label_undefined; 6125 if(!jit_insn_branch_if(func, cond_value, &label)) 6126 { 6127 return 0; 6128 } 6129 6130 /* Call the "jit_exception_builtin" function to report the exception */ 6131 param_types[0] = jit_type_int; 6132 signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 6133 param_types, 1, 1); 6134 if(!signature) 6135 { 6136 return 0; 6137 } 6138 param_values[0] = temp_value; 6139 jit_insn_call_native(func, "jit_exception_builtin", 6140 (void *) jit_exception_builtin, signature, 6141 param_values, 1, JIT_CALL_NORETURN); 6142 jit_type_free(signature); 6143 6144 /* Execution continues here if there was no exception */ 6145 if(!jit_insn_label_tight(func, &label)) 6146 { 6147 return 0; 6148 } 6149 6150 /* Return the temporary that contains the result value */ 6151 return return_value; 6152 } 6153 6154 /*@ 6155 * @deftypefun int jit_insn_incoming_reg (jit_function_t @var{func}, jit_value_t @var{value}, int @var{reg}) 6156 * Output an instruction that notes that the contents of @var{value} 6157 * can be found in the register @var{reg} at this point in the code. 6158 * 6159 * You normally wouldn't call this yourself - it is used internally 6160 * by the CPU back ends to set up the function's entry frame and the 6161 * values of registers on return from a subroutine call. 6162 * @end deftypefun 6163 @*/ 6164 int 6165 jit_insn_incoming_reg(jit_function_t func, jit_value_t value, int reg) 6166 { 6167 jit_value_t reg_value = jit_value_create_nint_constant(func, jit_type_int, reg); 6168 if(!reg_value) 6169 { 6170 return 0; 6171 } 6172 if(value->is_parameter) 6173 { 6174 value->is_reg_parameter = 1; 6175 } 6176 return create_note(func, JIT_OP_INCOMING_REG, value, reg_value); 6177 } 6178 6179 /*@ 6180 * @deftypefun int jit_insn_incoming_frame_posn (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{frame_offset}) 6181 * Output an instruction that notes that the contents of @var{value} 6182 * can be found in the stack frame at @var{frame_offset}. This should only be 6183 * called once per value, to prevent values from changing their address when 6184 * they might be addressable. 6185 * 6186 * You normally wouldn't call this yourself - it is used internally 6187 * by the CPU back ends to set up the function's entry frame. 6188 * @end deftypefun 6189 @*/ 6190 int 6191 jit_insn_incoming_frame_posn(jit_function_t func, jit_value_t value, 6192 jit_nint frame_offset) 6193 { 6194 jit_value_t frame_offset_value; 6195 6196 /* We need to set the value's frame_offset right now. As children have to be 6197 compiled before their parents there would otherwise be no way for a child 6198 to know the frame_offset the value will be in. */ 6199 if(!value->has_frame_offset) 6200 { 6201 value->has_frame_offset = 1; 6202 value->frame_offset = frame_offset; 6203 } 6204 6205 frame_offset_value 6206 = jit_value_create_nint_constant(func, jit_type_int, frame_offset); 6207 if(!frame_offset_value) 6208 { 6209 return 0; 6210 } 6211 return create_note(func, JIT_OP_INCOMING_FRAME_POSN, value, frame_offset_value); 6212 } 6213 6214 /*@ 6215 * @deftypefun int jit_insn_outgoing_reg (jit_function_t @var{func}, jit_value_t @var{value}, int @var{reg}) 6216 * Output an instruction that copies the contents of @var{value} 6217 * into the register @var{reg} at this point in the code. This is 6218 * typically used just before making an outgoing subroutine call. 6219 * 6220 * You normally wouldn't call this yourself - it is used internally 6221 * by the CPU back ends to set up the registers for a subroutine call. 6222 * @end deftypefun 6223 @*/ 6224 int 6225 jit_insn_outgoing_reg(jit_function_t func, jit_value_t value, int reg) 6226 { 6227 jit_value_t reg_value = jit_value_create_nint_constant(func, jit_type_int, reg); 6228 if(!reg_value) 6229 { 6230 return 0; 6231 } 6232 return create_note(func, JIT_OP_OUTGOING_REG, value, reg_value); 6233 } 6234 6235 /*@ 6236 * @deftypefun int jit_insn_outgoing_frame_posn (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{frame_offset}) 6237 * Output an instruction that stores the contents of @var{value} in 6238 * the stack frame at @var{frame_offset}. 6239 * 6240 * You normally wouldn't call this yourself - it is used internally 6241 * by the CPU back ends to set up an outgoing frame for tail calls. 6242 * @end deftypefun 6243 @*/ 6244 int 6245 jit_insn_outgoing_frame_posn(jit_function_t func, jit_value_t value, 6246 jit_nint frame_offset) 6247 { 6248 jit_value_t frame_pointer; 6249 6250 frame_pointer = jit_insn_get_frame_pointer(func); 6251 if(!frame_pointer) 6252 { 6253 return 0; 6254 } 6255 6256 return jit_insn_store_relative(func, frame_pointer, frame_offset, value); 6257 } 6258 6259 /*@ 6260 * @deftypefun int jit_insn_return_reg (jit_function_t @var{func}, jit_value_t @var{value}, int @var{reg}) 6261 * Output an instruction that notes that the contents of @var{value} 6262 * can be found in the register @var{reg} at this point in the code. 6263 * This is similar to @code{jit_insn_incoming_reg}, except that it 6264 * refers to return values, not parameter values. 6265 * 6266 * You normally wouldn't call this yourself - it is used internally 6267 * by the CPU back ends to handle returns from subroutine calls. 6268 * @end deftypefun 6269 @*/ 6270 int 6271 jit_insn_return_reg(jit_function_t func, jit_value_t value, int reg) 6272 { 6273 jit_value_t reg_value = jit_value_create_nint_constant(func, jit_type_int, reg); 6274 if(!reg_value) 6275 { 6276 return 0; 6277 } 6278 return create_note(func, JIT_OP_RETURN_REG, value, reg_value); 6279 } 6280 6281 /*@ 6282 * @deftypefun int jit_insn_flush_struct (jit_function_t @var{func}, jit_value_t @var{value}) 6283 * Flush a small structure return value out of registers and back 6284 * into the local variable frame. You normally wouldn't call this 6285 * yourself - it is used internally by the CPU back ends to handle 6286 * structure returns from functions. 6287 * @end deftypefun 6288 @*/ 6289 int 6290 jit_insn_flush_struct(jit_function_t func, jit_value_t value) 6291 { 6292 if(value) 6293 { 6294 jit_value_set_addressable(value); 6295 } 6296 return create_unary_note(func, JIT_OP_FLUSH_SMALL_STRUCT, value); 6297 } 6298 6299 /*@ 6300 * @deftypefun jit_value_t jit_insn_get_frame_pointer (jit_function_t @var{func}) 6301 * Retrieve the frame pointer of function @var{func} 6302 * Returns NULL if out of memory. 6303 * @end deftypefun 6304 @*/ 6305 jit_value_t 6306 jit_insn_get_frame_pointer(jit_function_t func) 6307 { 6308 return create_dest_note(func, JIT_OP_RETRIEVE_FRAME_POINTER, 6309 jit_type_void_ptr); 6310 } 6311 6312 static jit_value_t 6313 find_frame_of(jit_function_t func, jit_function_t target, 6314 jit_function_t func_start, jit_value_t frame_start) 6315 { 6316 /* Find the nesting level */ 6317 int nesting_level = 0; 6318 jit_function_t current_func = func_start; 6319 while(current_func != 0 && current_func != target) 6320 { 6321 /* Ensure that current_func has a function builder */ 6322 if(!_jit_function_ensure_builder(current_func)) 6323 { 6324 return 0; 6325 } 6326 6327 if(!current_func->parent_frame) 6328 { 6329 /* One of the ancestors is not correctly set up */ 6330 return 0; 6331 } 6332 6333 #ifdef JIT_BACKEND_INTERP 6334 if(!current_func->arguments_pointer) 6335 { 6336 /* Make sure the ancestor has an arguments_pointer, in case we are 6337 importing a parameter */ 6338 current_func->arguments_pointer = jit_value_create(current_func, 6339 jit_type_void_ptr); 6340 6341 if(!current_func->arguments_pointer) 6342 { 6343 return 0; 6344 } 6345 } 6346 #endif 6347 6348 current_func = current_func->nested_parent; 6349 nesting_level++; 6350 } 6351 if(!current_func) 6352 { 6353 /* The value is not accessible from this scope */ 6354 return 0; 6355 } 6356 6357 /* When we are importing a multi level nested value we need to import the 6358 frame pointer of the next nesting level using the frame pointer of the 6359 current level, until we reach our target function */ 6360 current_func = func_start; 6361 while(frame_start != 0 && nesting_level-- > 0) 6362 { 6363 frame_start = apply_binary(func, JIT_OP_IMPORT, frame_start, 6364 current_func->parent_frame, jit_type_void_ptr); 6365 frame_start = jit_insn_load_relative(func, frame_start, 0, 6366 jit_type_void_ptr); 6367 6368 current_func = current_func->nested_parent; 6369 } 6370 6371 if(!frame_start) 6372 { 6373 return 0; 6374 } 6375 6376 return frame_start; 6377 } 6378 6379 /*@ 6380 * @deftypefun jit_value_t jit_insn_get_parent_frame_pointer_of (jit_function_t @var{func}, jit_function_t @var{target}) 6381 * Retrieve the frame pointer of the parent of @var{target}. Returns NULL when 6382 * @var{target} is not a sibling, an ancestor, or a sibling of one of the 6383 * ancestors of @var{func}. 6384 * Returns NULL if out of memory. 6385 * @end deftypefun 6386 @*/ 6387 jit_value_t 6388 jit_insn_get_parent_frame_pointer_of(jit_function_t func, jit_function_t target) 6389 { 6390 if(func == target->nested_parent) 6391 { 6392 /* target is a child of the current function. We just need return 6393 our frame pointer */ 6394 return jit_insn_get_frame_pointer(func); 6395 } 6396 else 6397 { 6398 /* target is a sibling or a sibling of one of the ancestors of func. 6399 We need to find the parent of target in the ancestor tree of func */ 6400 return find_frame_of(func, target->nested_parent, 6401 func->nested_parent, func->parent_frame); 6402 } 6403 } 6404 6405 /*@ 6406 * @deftypefun jit_value_t jit_insn_import (jit_function_t @var{func}, jit_value_t @var{value}) 6407 * Import @var{value} from an outer nested scope into @var{func}. Returns 6408 * the effective address of the value for local access via a pointer. 6409 * Returns NULL if out of memory or the value is not accessible via a 6410 * parent, grandparent, or other ancestor of @var{func}. 6411 * @end deftypefun 6412 @*/ 6413 jit_value_t 6414 jit_insn_import(jit_function_t func, jit_value_t value) 6415 { 6416 jit_function_t value_func; 6417 jit_value_t value_frame; 6418 jit_type_t result_type; 6419 jit_value_t result; 6420 6421 /* Ensure that we have a function builder */ 6422 if(!_jit_function_ensure_builder(func)) 6423 { 6424 return 0; 6425 } 6426 6427 /* If the value is already local, then return the local address */ 6428 value_func = jit_value_get_function(value); 6429 if(value_func == func) 6430 { 6431 return jit_insn_address_of(func, value); 6432 } 6433 6434 #ifdef JIT_BACKEND_INTERP 6435 if(!value_func->arguments_pointer) 6436 { 6437 /* Make sure the ancestor has an arguments_pointer, in case we are 6438 importing a parameter */ 6439 value_func->arguments_pointer = jit_value_create(value_func, 6440 jit_type_void_ptr); 6441 6442 if(!value_func->arguments_pointer) 6443 { 6444 return 0; 6445 } 6446 } 6447 #endif 6448 6449 result_type = jit_type_create_pointer(jit_value_get_type(value), 1); 6450 if(!result_type) 6451 { 6452 return 0; 6453 } 6454 6455 /* Often there are multiple values imported from the same ancestor in a row, 6456 thats why the last ancestor a value was imported from is cached so its 6457 frame can be reused as finding it would require multiple memory loads */ 6458 if(value_func == func->cached_parent && func->cached_parent_frame) 6459 { 6460 value_frame = func->cached_parent_frame; 6461 } 6462 else 6463 { 6464 value_frame = find_frame_of(func, value_func, 6465 func->nested_parent, func->parent_frame); 6466 6467 func->cached_parent = value_func; 6468 func->cached_parent_frame = value_frame; 6469 } 6470 6471 if(!value_frame) 6472 { 6473 jit_type_free(result_type); 6474 return 0; 6475 } 6476 6477 result = apply_binary(func, JIT_OP_IMPORT, value_frame, value, result_type); 6478 jit_type_free(result_type); 6479 6480 return result; 6481 } 6482 6483 /*@ 6484 * @deftypefun int jit_insn_push (jit_function_t @var{func}, jit_value_t @var{value}) 6485 * Push a value onto the function call stack, in preparation for a call. 6486 * You normally wouldn't call this yourself - it is used internally 6487 * by the CPU back ends to set up the stack for a subroutine call. 6488 * @end deftypefun 6489 @*/ 6490 int 6491 jit_insn_push(jit_function_t func, jit_value_t value) 6492 { 6493 jit_type_t type = jit_value_get_type(value); 6494 type = jit_type_promote_int(jit_type_normalize(type)); 6495 6496 jit_value_t size_value; 6497 switch(type->kind) 6498 { 6499 case JIT_TYPE_SBYTE: 6500 case JIT_TYPE_UBYTE: 6501 case JIT_TYPE_SHORT: 6502 case JIT_TYPE_USHORT: 6503 case JIT_TYPE_INT: 6504 case JIT_TYPE_UINT: 6505 return create_unary_note(func, JIT_OP_PUSH_INT, value); 6506 6507 case JIT_TYPE_LONG: 6508 case JIT_TYPE_ULONG: 6509 return create_unary_note(func, JIT_OP_PUSH_LONG, value); 6510 6511 case JIT_TYPE_FLOAT32: 6512 return create_unary_note(func, JIT_OP_PUSH_FLOAT32, value); 6513 6514 case JIT_TYPE_FLOAT64: 6515 return create_unary_note(func, JIT_OP_PUSH_FLOAT64, value); 6516 6517 case JIT_TYPE_NFLOAT: 6518 return create_unary_note(func, JIT_OP_PUSH_NFLOAT, value); 6519 6520 case JIT_TYPE_STRUCT: 6521 case JIT_TYPE_UNION: 6522 /* We need the address of the value for "push_struct" */ 6523 value = jit_insn_address_of(func, value); 6524 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6525 jit_type_get_size(type)); 6526 if(!value || !size_value) 6527 { 6528 return 0; 6529 } 6530 return create_note(func, JIT_OP_PUSH_STRUCT, value, size_value); 6531 } 6532 6533 return 1; 6534 } 6535 6536 /*@ 6537 * @deftypefun int jit_insn_push_ptr (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{type}) 6538 * Push @code{*@var{value}} onto the function call stack, in preparation for a call. 6539 * This is normally used for returning @code{struct} and @code{union} 6540 * values where you have the effective address of the structure, rather 6541 * than the structure's contents, in @var{value}. 6542 * 6543 * You normally wouldn't call this yourself - it is used internally 6544 * by the CPU back ends to set up the stack for a subroutine call. 6545 * @end deftypefun 6546 @*/ 6547 int 6548 jit_insn_push_ptr(jit_function_t func, jit_value_t value, jit_type_t type) 6549 { 6550 jit_value_t size_value; 6551 switch(jit_type_remove_tags(type)->kind) 6552 { 6553 case JIT_TYPE_STRUCT: 6554 case JIT_TYPE_UNION: 6555 /* Push the structure onto the stack by address */ 6556 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6557 jit_type_get_size(type)); 6558 if(!size_value) 6559 { 6560 return 0; 6561 } 6562 return create_note(func, JIT_OP_PUSH_STRUCT, value, size_value); 6563 6564 default: 6565 /* Load the value from the address and push it normally */ 6566 value = jit_insn_load_relative(func, value, 0, type); 6567 if(!value) 6568 { 6569 return 0; 6570 } 6571 return jit_insn_push(func, value); 6572 } 6573 } 6574 6575 /*@ 6576 * @deftypefun int jit_insn_set_param (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{offset}) 6577 * Set the parameter slot at @var{offset} in the outgoing parameter area 6578 * to @var{value}. This may be used instead of @code{jit_insn_push} 6579 * if it is more efficient to store directly to the stack than to push. 6580 * The outgoing parameter area is allocated within the frame when 6581 * the function is first entered. 6582 * 6583 * You normally wouldn't call this yourself - it is used internally 6584 * by the CPU back ends to set up the stack for a subroutine call. 6585 * @end deftypefun 6586 @*/ 6587 int 6588 jit_insn_set_param(jit_function_t func, jit_value_t value, jit_nint offset) 6589 { 6590 jit_type_t type = jit_value_get_type(value); 6591 type = jit_type_promote_int(jit_type_normalize(type)); 6592 6593 jit_value_t offset_value, size_value; 6594 offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); 6595 if(!offset_value) 6596 { 6597 return 0; 6598 } 6599 6600 switch(type->kind) 6601 { 6602 case JIT_TYPE_SBYTE: 6603 case JIT_TYPE_UBYTE: 6604 case JIT_TYPE_SHORT: 6605 case JIT_TYPE_USHORT: 6606 case JIT_TYPE_INT: 6607 case JIT_TYPE_UINT: 6608 return create_note(func, JIT_OP_SET_PARAM_INT, value, offset_value); 6609 6610 case JIT_TYPE_LONG: 6611 case JIT_TYPE_ULONG: 6612 return create_note(func, JIT_OP_SET_PARAM_LONG, value, offset_value); 6613 6614 case JIT_TYPE_FLOAT32: 6615 return create_note(func, JIT_OP_SET_PARAM_FLOAT32, value, offset_value); 6616 6617 case JIT_TYPE_FLOAT64: 6618 return create_note(func, JIT_OP_SET_PARAM_FLOAT64, value, offset_value); 6619 6620 case JIT_TYPE_NFLOAT: 6621 return create_note(func, JIT_OP_SET_PARAM_NFLOAT, value, offset_value); 6622 6623 case JIT_TYPE_STRUCT: 6624 case JIT_TYPE_UNION: 6625 /* We need the address of the value for "push_struct" */ 6626 value = jit_insn_address_of(func, value); 6627 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6628 jit_type_get_size(type)); 6629 if(!value || !size_value) 6630 { 6631 return 0; 6632 } 6633 return apply_ternary(func, JIT_OP_SET_PARAM_STRUCT, offset_value, value, 6634 size_value); 6635 } 6636 return 1; 6637 } 6638 6639 /*@ 6640 * @deftypefun int jit_insn_set_param_ptr (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{type}, jit_nint @var{offset}) 6641 * Same as @code{jit_insn_set_param}, except that the parameter is 6642 * at @code{*@var{value}}. 6643 * @end deftypefun 6644 @*/ 6645 int 6646 jit_insn_set_param_ptr(jit_function_t func, jit_value_t value, jit_type_t type, 6647 jit_nint offset) 6648 { 6649 jit_value_t offset_value, size_value; 6650 switch(jit_type_remove_tags(type)->kind) 6651 { 6652 case JIT_TYPE_STRUCT: 6653 case JIT_TYPE_UNION: 6654 /* Set the structure into the parameter area by address */ 6655 offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset); 6656 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6657 jit_type_get_size(type)); 6658 if(!offset_value || !size_value) 6659 { 6660 return 0; 6661 } 6662 return apply_ternary(func, JIT_OP_SET_PARAM_STRUCT, offset_value, value, 6663 size_value); 6664 6665 default: 6666 /* Load the value from the address and set it normally */ 6667 value = jit_insn_load_relative(func, value, 0, type); 6668 if(!value) 6669 { 6670 return 0; 6671 } 6672 return jit_insn_set_param(func, value, offset); 6673 } 6674 } 6675 6676 /*@ 6677 * @deftypefun int jit_insn_push_return_area_ptr (jit_function_t @var{func}) 6678 * Push the interpreter's return area pointer onto the stack. 6679 * You normally wouldn't call this yourself - it is used internally 6680 * by the CPU back ends to set up the stack for a subroutine call. 6681 * @end deftypefun 6682 @*/ 6683 int 6684 jit_insn_push_return_area_ptr(jit_function_t func) 6685 { 6686 return create_noarg_note(func, JIT_OP_PUSH_RETURN_AREA_PTR); 6687 } 6688 6689 /*@ 6690 * @deftypefun int jit_insn_pop_stack (jit_function_t @var{func}, jit_nint @var{num_items}) 6691 * Pop @var{num_items} items from the function call stack. You normally 6692 * wouldn't call this yourself - it is used by CPU back ends to clean up 6693 * the stack after calling a subroutine. The size of an item is specific 6694 * to the back end (it could be bytes, words, or some other measurement). 6695 * @end deftypefun 6696 @*/ 6697 int 6698 jit_insn_pop_stack(jit_function_t func, jit_nint num_items) 6699 { 6700 jit_value_t num_value = jit_value_create_nint_constant(func, jit_type_nint, num_items); 6701 return create_unary_note(func, JIT_OP_POP_STACK, num_value); 6702 } 6703 6704 /*@ 6705 * @deftypefun int jit_insn_defer_pop_stack (jit_function_t @var{func}, jit_nint @var{num_items}) 6706 * This is similar to @code{jit_insn_pop_stack}, except that it tries to 6707 * defer the pop as long as possible. Multiple subroutine calls may 6708 * result in parameters collecting up on the stack, and only being popped 6709 * at the next branch or label instruction. You normally wouldn't 6710 * call this yourself - it is used by CPU back ends. 6711 * @end deftypefun 6712 @*/ 6713 int 6714 jit_insn_defer_pop_stack(jit_function_t func, jit_nint num_items) 6715 { 6716 /* Ensure that we have a function builder */ 6717 if(!_jit_function_ensure_builder(func)) 6718 { 6719 return 0; 6720 } 6721 6722 func->builder->deferred_items += num_items; 6723 return 1; 6724 } 6725 6726 /*@ 6727 * @deftypefun int jit_insn_flush_defer_pop (jit_function_t @var{func}, jit_nint @var{num_items}) 6728 * Flush any deferred items that were scheduled for popping by 6729 * @code{jit_insn_defer_pop_stack} if there are @var{num_items} 6730 * or more items scheduled. You normally wouldn't call this 6731 * yourself - it is used by CPU back ends to clean up the stack just 6732 * prior to a subroutine call when too many items have collected up. 6733 * Calling @code{jit_insn_flush_defer_pop(func, 0)} will flush 6734 * all deferred items. 6735 * @end deftypefun 6736 @*/ 6737 int 6738 jit_insn_flush_defer_pop(jit_function_t func, jit_nint num_items) 6739 { 6740 /* Ensure that we have a function builder */ 6741 if(!_jit_function_ensure_builder(func)) 6742 { 6743 return 0; 6744 } 6745 6746 jit_nint current_items = func->builder->deferred_items; 6747 if(current_items >= num_items && current_items > 0) 6748 { 6749 func->builder->deferred_items = 0; 6750 return jit_insn_pop_stack(func, current_items); 6751 } 6752 6753 return 1; 6754 } 6755 6756 /*@ 6757 * @deftypefun int jit_insn_return (jit_function_t @var{func}, jit_value_t @var{value}) 6758 * Output an instruction to return @var{value} as the function's result. 6759 * If @var{value} is NULL, then the function is assumed to return 6760 * @code{void}. If the function returns a structure, this will copy 6761 * the value into the memory at the structure return address. 6762 * @end deftypefun 6763 @*/ 6764 int 6765 jit_insn_return(jit_function_t func, jit_value_t value) 6766 { 6767 /* Ensure that we have a function builder */ 6768 if(!_jit_function_ensure_builder(func)) 6769 { 6770 return 0; 6771 } 6772 6773 #if !defined(JIT_BACKEND_INTERP) 6774 /* We need to pop the "setjmp" context */ 6775 if(func->has_try) 6776 { 6777 jit_type_t type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 1); 6778 if(!type) 6779 { 6780 return 0; 6781 } 6782 jit_insn_call_native(func, "_jit_unwind_pop_setjmp", 6783 (void *) _jit_unwind_pop_setjmp, type, 6784 0, 0, JIT_CALL_NOTHROW); 6785 jit_type_free(type); 6786 } 6787 #endif 6788 6789 /* This function has an ordinary return path */ 6790 func->builder->ordinary_return = 1; 6791 6792 /* Output an appropriate instruction to return to the caller */ 6793 jit_type_t type = jit_type_get_return(func->signature); 6794 type = jit_type_promote_int(jit_type_normalize(type)); 6795 if(!value || type == jit_type_void) 6796 { 6797 /* This function returns "void" */ 6798 if(!create_noarg_note(func, JIT_OP_RETURN)) 6799 { 6800 return 0; 6801 } 6802 } 6803 else 6804 { 6805 /* Convert the value into the desired return type */ 6806 value = jit_insn_convert(func, value, type, 0); 6807 if(!value) 6808 { 6809 return 0; 6810 } 6811 6812 /* Create the "return" instruction */ 6813 jit_value_t return_ptr, value_addr, size_value; 6814 switch(type->kind) 6815 { 6816 case JIT_TYPE_SBYTE: 6817 case JIT_TYPE_UBYTE: 6818 case JIT_TYPE_SHORT: 6819 case JIT_TYPE_USHORT: 6820 case JIT_TYPE_INT: 6821 case JIT_TYPE_UINT: 6822 if(!create_unary_note(func, JIT_OP_RETURN_INT, value)) 6823 { 6824 return 0; 6825 } 6826 break; 6827 6828 case JIT_TYPE_LONG: 6829 case JIT_TYPE_ULONG: 6830 if(!create_unary_note(func, JIT_OP_RETURN_LONG, value)) 6831 { 6832 return 0; 6833 } 6834 break; 6835 6836 case JIT_TYPE_FLOAT32: 6837 if(!create_unary_note(func, JIT_OP_RETURN_FLOAT32, value)) 6838 { 6839 return 0; 6840 } 6841 break; 6842 6843 case JIT_TYPE_FLOAT64: 6844 if(!create_unary_note(func, JIT_OP_RETURN_FLOAT64, value)) 6845 { 6846 return 0; 6847 } 6848 break; 6849 6850 case JIT_TYPE_NFLOAT: 6851 if(!create_unary_note(func, JIT_OP_RETURN_NFLOAT, value)) 6852 { 6853 return 0; 6854 } 6855 break; 6856 6857 case JIT_TYPE_STRUCT: 6858 case JIT_TYPE_UNION: 6859 value_addr = jit_insn_address_of(func, value); 6860 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6861 jit_type_get_size(type)); 6862 if(!value_addr || !size_value) 6863 { 6864 return 0; 6865 } 6866 6867 /* Determine the kind of structure return to use */ 6868 return_ptr = jit_value_get_struct_pointer(func); 6869 if(return_ptr) 6870 { 6871 /* Copy the structure's contents to the supplied 6872 pointer */ 6873 if(!jit_insn_memcpy(func, return_ptr, value_addr, size_value)) 6874 { 6875 return 0; 6876 } 6877 /* Output a regular return for the function */ 6878 if(!create_noarg_note(func, JIT_OP_RETURN)) 6879 { 6880 return 0; 6881 } 6882 } 6883 else 6884 { 6885 /* Return the structure via registers */ 6886 if(!create_note(func, JIT_OP_RETURN_SMALL_STRUCT, value_addr, 6887 size_value)) 6888 { 6889 return 0; 6890 } 6891 } 6892 break; 6893 } 6894 } 6895 6896 /* Mark the current block as "ends in dead" */ 6897 func->builder->current_block->ends_in_dead = 1; 6898 6899 /* Start a new block just after the "return" instruction */ 6900 return jit_insn_new_block(func); 6901 } 6902 6903 /*@ 6904 * @deftypefun int jit_insn_return_ptr (jit_function_t @var{func}, jit_value_t @var{value}, jit_type_t @var{type}) 6905 * Output an instruction to return @code{*@var{value}} as the function's result. 6906 * This is normally used for returning @code{struct} and @code{union} 6907 * values where you have the effective address of the structure, rather 6908 * than the structure's contents, in @var{value}. 6909 * @end deftypefun 6910 @*/ 6911 int 6912 jit_insn_return_ptr(jit_function_t func, jit_value_t value, jit_type_t type) 6913 { 6914 /* Ensure that we have a function builder */ 6915 if(!_jit_function_ensure_builder(func)) 6916 { 6917 return 0; 6918 } 6919 6920 #if !defined(JIT_BACKEND_INTERP) 6921 /* We need to pop the "setjmp" context */ 6922 if(func->has_try) 6923 { 6924 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 1); 6925 if(!type) 6926 { 6927 return 0; 6928 } 6929 jit_insn_call_native(func, "_jit_unwind_pop_setjmp", 6930 (void *) _jit_unwind_pop_setjmp, type, 6931 0, 0, JIT_CALL_NOTHROW); 6932 jit_type_free(type); 6933 } 6934 #endif 6935 6936 /* This function has an ordinary return path */ 6937 func->builder->ordinary_return = 1; 6938 6939 /* Convert the value into a pointer */ 6940 value = jit_insn_convert(func, value, jit_type_void_ptr, 0); 6941 if(!value) 6942 { 6943 return 0; 6944 } 6945 6946 /* Determine how to return the value, based on the pointed-to type */ 6947 jit_value_t return_ptr, size_value; 6948 switch(jit_type_remove_tags(type)->kind) 6949 { 6950 case JIT_TYPE_STRUCT: 6951 case JIT_TYPE_UNION: 6952 size_value = jit_value_create_nint_constant(func, jit_type_nint, 6953 jit_type_get_size(type)); 6954 if(!size_value) 6955 { 6956 return 0; 6957 } 6958 6959 /* Determine the kind of structure return to use */ 6960 return_ptr = jit_value_get_struct_pointer(func); 6961 if(return_ptr) 6962 { 6963 /* Copy the structure's contents to the supplied pointer */ 6964 if(!jit_insn_memcpy(func, return_ptr, value, size_value)) 6965 { 6966 return 0; 6967 } 6968 /* Output a regular return for the function */ 6969 if(!create_noarg_note(func, JIT_OP_RETURN)) 6970 { 6971 return 0; 6972 } 6973 } 6974 else 6975 { 6976 /* Return the structure via registers */ 6977 if(!create_note(func, JIT_OP_RETURN_SMALL_STRUCT, value, size_value)) 6978 { 6979 return 0; 6980 } 6981 } 6982 break; 6983 6984 default: 6985 /* Everything else uses the normal return logic */ 6986 value = jit_insn_load_relative(func, value, 0, type); 6987 if(!value) 6988 { 6989 return 0; 6990 } 6991 return jit_insn_return(func, value); 6992 } 6993 6994 /* Mark the current block as "ends in dead" */ 6995 func->builder->current_block->ends_in_dead = 1; 6996 6997 /* Start a new block just after the "return" instruction */ 6998 return jit_insn_new_block(func); 6999 } 7000 7001 /*@ 7002 * @deftypefun int jit_insn_default_return (jit_function_t @var{func}) 7003 * Add an instruction to return a default value if control reaches this point. 7004 * This is typically used at the end of a function to ensure that all paths 7005 * return to the caller. Returns zero if out of memory, 1 if a default 7006 * return was added, and 2 if a default return was not needed. 7007 * 7008 * Note: if this returns 1, but the function signature does not return 7009 * @code{void}, then it indicates that a higher-level language error 7010 * has occurred and the function should be abandoned. 7011 * @end deftypefun 7012 @*/ 7013 int 7014 jit_insn_default_return(jit_function_t func) 7015 { 7016 /* Ensure that we have a function builder */ 7017 if(!_jit_function_ensure_builder(func)) 7018 { 7019 return 0; 7020 } 7021 7022 /* If the last block ends in an unconditional branch, or is dead, 7023 then we don't need to add a default return */ 7024 if(jit_block_current_is_dead(func)) 7025 { 7026 return 2; 7027 } 7028 7029 /* Add a simple "void" return to terminate the function */ 7030 return jit_insn_return(func, 0); 7031 } 7032 7033 /*@ 7034 * @deftypefun int jit_insn_throw (jit_function_t @var{func}, jit_value_t @var{value}) 7035 * Throw a pointer @var{value} as an exception object. This can also 7036 * be used to "rethrow" an object from a catch handler that is not 7037 * interested in handling the exception. 7038 * @end deftypefun 7039 @*/ 7040 int 7041 jit_insn_throw(jit_function_t func, jit_value_t value) 7042 { 7043 /* Ensure that we have a function builder */ 7044 if(!_jit_function_ensure_builder(func)) 7045 { 7046 return 0; 7047 } 7048 7049 func->builder->may_throw = 1; 7050 func->builder->non_leaf = 1; /* May have to call out to throw */ 7051 if(!create_unary_note(func, JIT_OP_THROW, value)) 7052 { 7053 return 0; 7054 } 7055 func->builder->current_block->ends_in_dead = 1; 7056 return jit_insn_new_block(func); 7057 } 7058 7059 /*@ 7060 * @deftypefun jit_value_t jit_insn_get_call_stack (jit_function_t @var{func}) 7061 * Get an object that represents the current position in the code, 7062 * and all of the functions that are currently on the call stack. 7063 * This is equivalent to calling @code{jit_exception_get_stack_trace}, 7064 * and is normally used just prior to @code{jit_insn_throw} to record 7065 * the location of the exception that is being thrown. 7066 * @end deftypefun 7067 @*/ 7068 jit_value_t 7069 jit_insn_get_call_stack(jit_function_t func) 7070 { 7071 /* Create a signature prototype for "void *()" */ 7072 jit_type_t type = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, 0, 0, 1); 7073 if(!type) 7074 { 7075 return 0; 7076 } 7077 7078 /* Call "jit_exception_get_stack_trace" to obtain the stack trace */ 7079 jit_value_t value 7080 = jit_insn_call_native(func, "jit_exception_get_stack_trace", 7081 (void *) jit_exception_get_stack_trace, 7082 type, 0, 0, 0); 7083 7084 /* Clean up and exit */ 7085 jit_type_free(type); 7086 return value; 7087 } 7088 7089 /*@ 7090 * @deftypefun jit_value_t jit_insn_thrown_exception (jit_function_t @var{func}) 7091 * Get the value that holds the most recent thrown exception. This is 7092 * typically used in @code{catch} clauses. 7093 * @end deftypefun 7094 @*/ 7095 jit_value_t 7096 jit_insn_thrown_exception(jit_function_t func) 7097 { 7098 /* Ensure that we have a function builder */ 7099 if(!_jit_function_ensure_builder(func)) 7100 { 7101 return 0; 7102 } 7103 7104 if(!func->builder->thrown_exception) 7105 { 7106 func->builder->thrown_exception = 7107 jit_value_create(func, jit_type_void_ptr); 7108 } 7109 return func->builder->thrown_exception; 7110 } 7111 7112 /* 7113 * Initialize the "setjmp" setup block that is needed to catch exceptions 7114 * thrown back to this level of execution. The block looks like this: 7115 * 7116 * jit_jmp_buf jbuf; 7117 * void *catcher; 7118 * 7119 * _jit_unwind_push_setjmp(&jbuf); 7120 * if(setjmp(&jbuf.buf)) 7121 * { 7122 * catch_pc = jbuf.catch_pc; 7123 * if(catch_pc) 7124 * { 7125 * jbuf.catch_pc = 0; 7126 * goto *catcher; 7127 * } 7128 * else 7129 * { 7130 * _jit_unwind_pop_and_rethrow(); 7131 * } 7132 * } 7133 * 7134 * The field "jbuf.catch_pc" will be set to the address of the relevant 7135 * "catch" block just before a subroutine call that may involve exceptions. 7136 * It will be reset to NULL after such subroutine calls. 7137 * 7138 * Native back ends are responsible for outputting a call to the function 7139 * "_jit_unwind_pop_setjmp()" just before "return" instructions if the 7140 * "has_try" flag is set on the function. 7141 */ 7142 static int 7143 initialize_setjmp_block(jit_function_t func) 7144 { 7145 #if !defined(JIT_BACKEND_INTERP) 7146 jit_label_t start_label = jit_label_undefined; 7147 jit_label_t end_label = jit_label_undefined; 7148 jit_label_t code_label = jit_label_undefined; 7149 jit_label_t rethrow_label = jit_label_undefined; 7150 jit_value_t args[2]; 7151 jit_value_t value; 7152 7153 /* Bail out if we have already done this before */ 7154 if(func->builder->setjmp_value) 7155 { 7156 return 1; 7157 } 7158 func->builder->catcher_label = jit_label_undefined; 7159 7160 /* Force the start of a new block to mark the start of the init code */ 7161 if(!jit_insn_label_tight(func, &start_label)) 7162 { 7163 return 0; 7164 } 7165 7166 /* Create a value to hold an item of type "jit_jmp_buf" */ 7167 jit_type_t type = jit_type_create_struct(0, 0, 1); 7168 if(!type) 7169 { 7170 return 0; 7171 } 7172 jit_type_set_size_and_alignment(type, sizeof(jit_jmp_buf), JIT_BEST_ALIGNMENT); 7173 func->builder->setjmp_value = jit_value_create(func, type); 7174 if(!func->builder->setjmp_value) 7175 { 7176 jit_type_free(type); 7177 return 0; 7178 } 7179 jit_type_free(type); 7180 7181 /* Call "_jit_unwind_push_setjmp" with "&setjmp_value" as its argument */ 7182 type = jit_type_void_ptr; 7183 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, &type, 1, 1); 7184 if(!type) 7185 { 7186 return 0; 7187 } 7188 args[0] = jit_insn_address_of(func, func->builder->setjmp_value); 7189 if(!args[0]) 7190 { 7191 return 0; 7192 } 7193 jit_insn_call_native(func, "_jit_unwind_push_setjmp", 7194 (void *) _jit_unwind_push_setjmp, type, 7195 args, 1, JIT_CALL_NOTHROW); 7196 jit_type_free(type); 7197 7198 /* Call "__sigsetjmp" or "setjmp" with "&setjmp_value" as its argument. 7199 We prefer "__sigsetjmp" because it is least likely to be a macro */ 7200 #if defined(HAVE___SIGSETJMP) || defined(HAVE_SIGSETJMP) 7201 { 7202 jit_type_t params[2]; 7203 params[0] = jit_type_void_ptr; 7204 params[1] = jit_type_sys_int; 7205 type = jit_type_create_signature(jit_abi_cdecl, jit_type_int, params, 2, 1); 7206 if(!type) 7207 { 7208 return 0; 7209 } 7210 } 7211 args[0] = jit_insn_address_of(func, func->builder->setjmp_value); 7212 args[1] = jit_value_create_nint_constant(func, jit_type_sys_int, 1); 7213 if(!args[0] || !args[1]) 7214 { 7215 jit_type_free(type); 7216 return 0; 7217 } 7218 #if defined(HAVE___SIGSETJMP) 7219 value = jit_insn_call_native(func, "__sigsetjmp", (void *) __sigsetjmp, 7220 type, args, 2, JIT_CALL_NOTHROW); 7221 #else 7222 value = jit_insn_call_native(func, "sigsetjmp", (void *) sigsetjmp, 7223 type, args, 2, JIT_CALL_NOTHROW); 7224 #endif 7225 jit_type_free(type); 7226 if(!value) 7227 { 7228 return 0; 7229 } 7230 #else /* !HAVE_SIGSETJMP */ 7231 type = jit_type_void_ptr; 7232 type = jit_type_create_signature(jit_abi_cdecl, jit_type_int, &type, 1, 1); 7233 if(!type) 7234 { 7235 return 0; 7236 } 7237 args[0] = jit_insn_address_of(func, func->builder->setjmp_value); 7238 if(!args[0]) 7239 { 7240 jit_type_free(type); 7241 return 0; 7242 } 7243 #if defined(HAVE__SETJMP) 7244 value = jit_insn_call_native(func, "_setjmp", (void *) _setjmp, 7245 type, args, 1, JIT_CALL_NOTHROW); 7246 7247 #else 7248 value = jit_insn_call_native(func, "setjmp", (void *) setjmp, 7249 type, args, 1, JIT_CALL_NOTHROW); 7250 #endif 7251 7252 jit_type_free(type); 7253 if(!value) 7254 { 7255 return 0; 7256 } 7257 #endif /* !HAVE_SIGSETJMP */ 7258 7259 /* Branch to the end of the init code if "setjmp" returned zero */ 7260 if(!jit_insn_branch_if_not(func, value, &code_label)) 7261 { 7262 return 0; 7263 } 7264 7265 /* We need a value to hold the location of the thrown exception */ 7266 func->builder->thrown_pc = jit_value_create(func, jit_type_void_ptr); 7267 if(func->builder->thrown_pc == 0) 7268 { 7269 return 0; 7270 } 7271 7272 /* Get the value of "catch_pc" from within "setjmp_value" and store it 7273 into the current frame. This indicates where the exception occurred */ 7274 value = jit_insn_address_of(func, func->builder->setjmp_value); 7275 if(!value) 7276 { 7277 return 0; 7278 } 7279 value = jit_insn_load_relative(func, value, jit_jmp_catch_pc_offset, jit_type_void_ptr); 7280 if(!value) 7281 { 7282 return 0; 7283 } 7284 if(!jit_insn_store(func, func->builder->thrown_pc, value)) 7285 { 7286 return 0; 7287 } 7288 if(!jit_insn_branch_if_not(func, value, &rethrow_label)) 7289 { 7290 return 0; 7291 } 7292 7293 /* Clear the original "catch_pc" value within "setjmp_value" */ 7294 jit_value_t null = jit_value_create_nint_constant(func, jit_type_void_ptr, 0); 7295 value = jit_insn_address_of(func, func->builder->setjmp_value); 7296 if(!null || !value) 7297 { 7298 return 0; 7299 } 7300 if(!jit_insn_store_relative(func, value, jit_jmp_catch_pc_offset, null)) 7301 { 7302 return 0; 7303 } 7304 7305 /* Jump to this function's exception catcher */ 7306 if(!jit_insn_branch(func, &func->builder->catcher_label)) 7307 { 7308 return 0; 7309 } 7310 7311 /* Mark the position of the rethrow label */ 7312 if(!jit_insn_label_tight(func, &rethrow_label)) 7313 { 7314 return 0; 7315 } 7316 7317 /* Call "_jit_unwind_pop_and_rethrow" to pop the current 7318 "setjmp" context and then rethrow the current exception */ 7319 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 1); 7320 if(!type) 7321 { 7322 return 0; 7323 } 7324 jit_insn_call_native(func, "_jit_unwind_pop_and_rethrow", 7325 (void *) _jit_unwind_pop_and_rethrow, type, 0, 0, 7326 JIT_CALL_NOTHROW | JIT_CALL_NORETURN); 7327 jit_type_free(type); 7328 7329 /* Insert the target to jump to the normal code. */ 7330 if(!jit_insn_label_tight(func, &code_label)) 7331 { 7332 return 0; 7333 } 7334 7335 /* Force the start of a new block to mark the end of the init code */ 7336 if(!jit_insn_label(func, &end_label)) 7337 { 7338 return 0; 7339 } 7340 7341 /* Move the initialization code to the head of the function so that 7342 it is performed once upon entry to the function */ 7343 return jit_insn_move_blocks_to_start(func, start_label, end_label); 7344 #else 7345 /* The interpreter doesn't need the "setjmp" setup block */ 7346 func->builder->catcher_label = jit_label_undefined; 7347 return 1; 7348 #endif 7349 } 7350 7351 /*@ 7352 * @deftypefun int jit_insn_uses_catcher (jit_function_t @var{func}) 7353 * Notify the function building process that @var{func} contains 7354 * some form of @code{catch} clause for catching exceptions. This must 7355 * be called before any instruction that is covered by a @code{try}, 7356 * ideally at the start of the function output process. 7357 * @end deftypefun 7358 @*/ 7359 int 7360 jit_insn_uses_catcher(jit_function_t func) 7361 { 7362 /* Ensure that we have a function builder */ 7363 if(!_jit_function_ensure_builder(func)) 7364 { 7365 return 0; 7366 } 7367 7368 if(func->has_try) 7369 { 7370 return 1; 7371 } 7372 func->has_try = 1; 7373 func->builder->may_throw = 1; 7374 func->builder->non_leaf = 1; 7375 return initialize_setjmp_block(func); 7376 } 7377 7378 /*@ 7379 * @deftypefun jit_value_t jit_insn_start_catcher (jit_function_t @var{func}) 7380 * Start the catcher block for @var{func}. There should be exactly one 7381 * catcher block for any function that involves a @code{try}. All 7382 * exceptions that are thrown within the function will cause control 7383 * to jump to this point. Returns a value that holds the exception 7384 * that was thrown. 7385 * @end deftypefun 7386 @*/ 7387 jit_value_t 7388 jit_insn_start_catcher(jit_function_t func) 7389 { 7390 /* Ensure that we have a function builder */ 7391 if(!_jit_function_ensure_builder(func)) 7392 { 7393 return 0; 7394 } 7395 7396 if(!jit_insn_label_tight(func, &func->builder->catcher_label)) 7397 { 7398 return 0; 7399 } 7400 jit_value_t value = jit_insn_thrown_exception(func); 7401 if(!value) 7402 { 7403 return 0; 7404 } 7405 #if defined(JIT_BACKEND_INTERP) 7406 /* In the interpreter, the exception object will be on the top of 7407 the operand stack when control reaches the catcher */ 7408 if(!jit_insn_incoming_reg(func, value, 0)) 7409 { 7410 return 0; 7411 } 7412 #else 7413 jit_type_t type = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, 0, 0, 1); 7414 if(!type) 7415 { 7416 return 0; 7417 } 7418 jit_value_t last_exception 7419 = jit_insn_call_native(func, "jit_exception_get_last", 7420 (void *) jit_exception_get_last, 7421 type, 0, 0, JIT_CALL_NOTHROW); 7422 jit_insn_store(func, value, last_exception); 7423 jit_type_free(type); 7424 #endif 7425 return value; 7426 } 7427 7428 /*@ 7429 * @deftypefun int jit_insn_branch_if_pc_not_in_range (jit_function_t @var{func}, jit_label_t @var{start_label}, jit_label_t @var{end_label}, jit_label_t *@var{label}) 7430 * Branch to @var{label} if the program counter where an exception occurred 7431 * does not fall between @var{start_label} and @var{end_label}. 7432 * @end deftypefun 7433 @*/ 7434 int 7435 jit_insn_branch_if_pc_not_in_range(jit_function_t func, jit_label_t start_label, 7436 jit_label_t end_label, jit_label_t *label) 7437 { 7438 /* Ensure that we have a function builder and a try block */ 7439 if(!_jit_function_ensure_builder(func)) 7440 { 7441 return 0; 7442 } 7443 if(!func->has_try) 7444 { 7445 return 0; 7446 } 7447 7448 /* Flush any stack pops that were deferred previously */ 7449 if(!jit_insn_flush_defer_pop(func, 0)) 7450 { 7451 return 0; 7452 } 7453 7454 /* Get the location where the exception occurred in this function */ 7455 #if defined(JIT_BACKEND_INTERP) 7456 jit_value_t value1 = create_dest_note(func, JIT_OP_LOAD_EXCEPTION_PC, jit_type_void_ptr); 7457 #else 7458 jit_value_t value1 = func->builder->thrown_pc; 7459 #endif 7460 if(!value1) 7461 { 7462 return 0; 7463 } 7464 7465 /* Compare the location against the start and end labels */ 7466 jit_value_t value2 = jit_insn_address_of_label(func, &start_label); 7467 if(!value2) 7468 { 7469 return 0; 7470 } 7471 value2 = jit_insn_lt(func, value1, value2); 7472 if(!value2 || !jit_insn_branch_if(func, value2, label)) 7473 { 7474 return 0; 7475 } 7476 value2 = jit_insn_address_of_label(func, &end_label); 7477 if(!value2) 7478 { 7479 return 0; 7480 } 7481 value2 = jit_insn_ge(func, value1, value2); 7482 if(!value2 || !jit_insn_branch_if(func, value2, label)) 7483 { 7484 return 0; 7485 } 7486 7487 /* If control gets here, then we have a location match */ 7488 return 1; 7489 } 7490 7491 /*@ 7492 * @deftypefun int jit_insn_rethrow_unhandled (jit_function_t @var{func}) 7493 * Rethrow the current exception because it cannot be handled by 7494 * any of the @code{catch} blocks in the current function. 7495 * 7496 * Note: this is intended for use within catcher blocks. It should not 7497 * be used to rethrow exceptions in response to programmer requests 7498 * (e.g. @code{throw;} in C#). The @code{jit_insn_throw} function 7499 * should be used for that purpose. 7500 * @end deftypefun 7501 @*/ 7502 int 7503 jit_insn_rethrow_unhandled(jit_function_t func) 7504 { 7505 /* Ensure that we have a function builder */ 7506 if(!_jit_function_ensure_builder(func)) 7507 { 7508 return 0; 7509 } 7510 7511 /* Get the current exception value to be thrown */ 7512 jit_value_t value = jit_insn_thrown_exception(func); 7513 if(!value) 7514 { 7515 return 0; 7516 } 7517 7518 #if defined(JIT_BACKEND_INTERP) 7519 7520 /* Rethrow the current exception (interpreter version) */ 7521 if(!create_unary_note(func, JIT_OP_RETHROW, value)) 7522 { 7523 return 0; 7524 } 7525 7526 #else /* !JIT_BACKEND_INTERP */ 7527 7528 /* Call "_jit_unwind_pop_setjmp" to remove the current exception catcher */ 7529 jit_type_t type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, 0, 0, 1); 7530 if(!type) 7531 { 7532 return 0; 7533 } 7534 jit_insn_call_native(func, "_jit_unwind_pop_setjmp", 7535 (void *) _jit_unwind_pop_setjmp, type, 0, 0, 7536 JIT_CALL_NOTHROW); 7537 jit_type_free(type); 7538 7539 /* Call the "jit_exception_throw" function to effect the rethrow */ 7540 type = jit_type_void_ptr; 7541 type = jit_type_create_signature(jit_abi_cdecl, jit_type_void, &type, 1, 1); 7542 if(!type) 7543 { 7544 return 0; 7545 } 7546 jit_insn_call_native(func, "jit_exception_throw", 7547 (void *) jit_exception_throw, type, &value, 1, 7548 JIT_CALL_NOTHROW | JIT_CALL_NORETURN); 7549 jit_type_free(type); 7550 7551 #endif /* !JIT_BACKEND_INTERP */ 7552 7553 /* The current block ends in dead and we need to start a new block */ 7554 func->builder->current_block->ends_in_dead = 1; 7555 return jit_insn_new_block(func); 7556 } 7557 7558 /*@ 7559 * @deftypefun int jit_insn_start_finally (jit_function_t @var{func}, jit_label_t *@var{finally_label}) 7560 * Start a @code{finally} clause. 7561 * @end deftypefun 7562 @*/ 7563 int 7564 jit_insn_start_finally(jit_function_t func, jit_label_t *finally_label) 7565 { 7566 if(!jit_insn_label_tight(func, finally_label)) 7567 { 7568 return 0; 7569 } 7570 return create_noarg_note(func, JIT_OP_ENTER_FINALLY); 7571 } 7572 7573 /*@ 7574 * @deftypefun int jit_insn_return_from_finally (jit_function_t @var{func}) 7575 * Return from the @code{finally} clause to where it was called from. 7576 * This is usually the last instruction in a @code{finally} clause. 7577 * @end deftypefun 7578 @*/ 7579 int 7580 jit_insn_return_from_finally(jit_function_t func) 7581 { 7582 /* Flush any deferred stack pops before we return */ 7583 if(!jit_insn_flush_defer_pop(func, 0)) 7584 { 7585 return 0; 7586 } 7587 7588 /* Mark the end of the "finally" clause */ 7589 if(!create_noarg_note(func, JIT_OP_LEAVE_FINALLY)) 7590 { 7591 return 0; 7592 } 7593 7594 /* The current block ends in a dead instruction */ 7595 func->builder->current_block->ends_in_dead = 1; 7596 7597 /* Create a new block for the following code */ 7598 return jit_insn_new_block(func); 7599 } 7600 7601 /*@ 7602 * @deftypefun int jit_insn_call_finally (jit_function_t @var{func}, jit_label_t *@var{finally_label}) 7603 * Call a @code{finally} clause. 7604 * @end deftypefun 7605 @*/ 7606 int 7607 jit_insn_call_finally(jit_function_t func, jit_label_t *finally_label) 7608 { 7609 /* Ensure that we have a function builder */ 7610 if(!_jit_function_ensure_builder(func)) 7611 { 7612 return 0; 7613 } 7614 7615 /* Flush any stack pops that were deferred previously */ 7616 if(!jit_insn_flush_defer_pop(func, 0)) 7617 { 7618 return 0; 7619 } 7620 7621 /* Allocate the label number if necessary */ 7622 if(*finally_label == jit_label_undefined) 7623 { 7624 *finally_label = func->builder->next_label++; 7625 } 7626 7627 /* Calling a finally handler makes the function not a leaf because 7628 we may need to do a native "call" to invoke the handler */ 7629 func->builder->non_leaf = 1; 7630 7631 /* Add a new branch instruction to branch to the finally handler */ 7632 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 7633 if(!insn) 7634 { 7635 return 0; 7636 } 7637 insn->opcode = (short) JIT_OP_CALL_FINALLY; 7638 insn->flags = JIT_INSN_DEST_IS_LABEL; 7639 insn->dest = (jit_value_t) *finally_label; 7640 7641 /* Create a new block for the following code */ 7642 return jit_insn_new_block(func); 7643 } 7644 7645 /*@ 7646 * @deftypefun jit_value_t jit_insn_start_filter (jit_function_t @var{func}, jit_label_t *@var{label}, jit_type_t @var{type}) 7647 * Define the start of a filter. Filters are embedded subroutines within 7648 * functions that are used to filter exceptions in @code{catch} blocks. 7649 * 7650 * A filter subroutine takes a single argument (usually a pointer) and 7651 * returns a single result (usually a boolean). The filter has complete 7652 * access to the local variables of the function, and can use any of 7653 * them in the filtering process. 7654 * 7655 * This function returns a temporary value of the specified @var{type}, 7656 * indicating the parameter that is supplied to the filter. 7657 * @end deftypefun 7658 @*/ 7659 jit_value_t 7660 jit_insn_start_filter(jit_function_t func, jit_label_t *label, jit_type_t type) 7661 { 7662 /* Set a label at this point to start a new block */ 7663 if(!jit_insn_label_tight(func, label)) 7664 { 7665 return 0; 7666 } 7667 7668 /* Create a note to load the filter's parameter at runtime */ 7669 return create_dest_note(func, JIT_OP_ENTER_FILTER, type); 7670 } 7671 7672 /*@ 7673 * @deftypefun int jit_insn_return_from_filter (jit_function_t @var{func}, jit_value_t @var{value}) 7674 * Return from a filter subroutine with the specified @code{value} as 7675 * its result. 7676 * @end deftypefun 7677 @*/ 7678 int 7679 jit_insn_return_from_filter(jit_function_t func, jit_value_t value) 7680 { 7681 /* Flush any deferred stack pops before we return */ 7682 if(!jit_insn_flush_defer_pop(func, 0)) 7683 { 7684 return 0; 7685 } 7686 7687 /* Mark the end of the "filter" clause */ 7688 if(!create_unary_note(func, JIT_OP_LEAVE_FILTER, value)) 7689 { 7690 return 0; 7691 } 7692 7693 /* The current block ends in a dead instruction */ 7694 func->builder->current_block->ends_in_dead = 1; 7695 7696 /* Create a new block for the following code */ 7697 return jit_insn_new_block(func); 7698 } 7699 7700 /*@ 7701 * @deftypefun jit_value_t jit_insn_call_filter (jit_function_t @var{func}, jit_label_t *@var{label}, jit_value_t @var{value}, jit_type_t @var{type}) 7702 * Call the filter subroutine at @var{label}, passing it @var{value} as 7703 * its argument. This function returns a value of the specified 7704 * @var{type}, indicating the filter's result. 7705 * @end deftypefun 7706 @*/ 7707 jit_value_t 7708 jit_insn_call_filter(jit_function_t func, jit_label_t *label, 7709 jit_value_t value, jit_type_t type) 7710 { 7711 /* Ensure that we have a function builder */ 7712 if(!_jit_function_ensure_builder(func)) 7713 { 7714 return 0; 7715 } 7716 7717 /* Flush any stack pops that were deferred previously */ 7718 if(!jit_insn_flush_defer_pop(func, 0)) 7719 { 7720 return 0; 7721 } 7722 7723 /* Allocate the label number if necessary */ 7724 if(*label == jit_label_undefined) 7725 { 7726 *label = func->builder->next_label++; 7727 } 7728 7729 /* Calling a filter makes the function not a leaf because we may 7730 need to do a native "call" to invoke the handler */ 7731 func->builder->non_leaf = 1; 7732 7733 /* Add a new branch instruction to branch to the filter */ 7734 jit_insn_t insn = _jit_block_add_insn(func->builder->current_block); 7735 if(!insn) 7736 { 7737 return 0; 7738 } 7739 insn->opcode = (short) JIT_OP_CALL_FILTER; 7740 insn->flags = JIT_INSN_DEST_IS_LABEL; 7741 insn->dest = (jit_value_t) *label; 7742 insn->value1 = value; 7743 jit_value_ref(func, value); 7744 7745 /* Create a new block, and add the filter return logic to it */ 7746 if(!jit_insn_new_block(func)) 7747 { 7748 return 0; 7749 } 7750 return create_dest_note(func, JIT_OP_CALL_FILTER_RETURN, type); 7751 } 7752 7753 /*@ 7754 * @deftypefun int jit_insn_memcpy (jit_function_t @var{func}, jit_value_t @var{dest}, jit_value_t @var{src}, jit_value_t @var{size}) 7755 * Copy the @var{size} bytes of memory at @var{src} to @var{dest}. 7756 * It is assumed that the source and destination do not overlap. 7757 * @end deftypefun 7758 @*/ 7759 int 7760 jit_insn_memcpy(jit_function_t func, jit_value_t dest, jit_value_t src, jit_value_t size) 7761 { 7762 size = jit_insn_convert(func, size, jit_type_nint, 0); 7763 if(!size) 7764 { 7765 return 0; 7766 } 7767 return apply_ternary(func, JIT_OP_MEMCPY, dest, src, size); 7768 } 7769 7770 /*@ 7771 * @deftypefun int jit_insn_memmove (jit_function_t @var{func}, jit_value_t @var{dest}, jit_value_t @var{src}, jit_value_t @var{size}) 7772 * Copy the @var{size} bytes of memory at @var{src} to @var{dest}. 7773 * This is save to use if the source and destination overlap. 7774 * @end deftypefun 7775 @*/ 7776 int 7777 jit_insn_memmove(jit_function_t func, jit_value_t dest, jit_value_t src, jit_value_t size) 7778 { 7779 size = jit_insn_convert(func, size, jit_type_nint, 0); 7780 if(!size) 7781 { 7782 return 0; 7783 } 7784 return apply_ternary(func, JIT_OP_MEMMOVE, dest, src, size); 7785 } 7786 7787 /*@ 7788 * @deftypefun int jit_insn_memset (jit_function_t @var{func}, jit_value_t @var{dest}, jit_value_t @var{value}, jit_value_t @var{size}) 7789 * Set the @var{size} bytes at @var{dest} to @var{value}. 7790 * @end deftypefun 7791 @*/ 7792 int 7793 jit_insn_memset(jit_function_t func, jit_value_t dest, jit_value_t value, jit_value_t size) 7794 { 7795 value = jit_insn_convert(func, value, jit_type_int, 0); 7796 size = jit_insn_convert(func, size, jit_type_nint, 0); 7797 if(!value || !size) 7798 { 7799 return 0; 7800 } 7801 return apply_ternary(func, JIT_OP_MEMSET, dest, value, size); 7802 } 7803 7804 /*@ 7805 * @deftypefun jit_value_t jit_insn_alloca (jit_function_t @var{func}, jit_value_t @var{size}) 7806 * Allocate @var{size} bytes of memory from the stack. 7807 * @end deftypefun 7808 @*/ 7809 jit_value_t 7810 jit_insn_alloca(jit_function_t func, jit_value_t size) 7811 { 7812 /* Make sure that all deferred pops have been done */ 7813 if(!jit_insn_flush_defer_pop(func, 0)) 7814 { 7815 return 0; 7816 } 7817 7818 /* Round the size to the best alignment boundary on this platform */ 7819 size = jit_insn_convert(func, size, jit_type_nuint, 0); 7820 jit_value_t addon = jit_value_create_nint_constant( 7821 func, jit_type_nuint, JIT_BEST_ALIGNMENT - 1); 7822 jit_value_t mask = jit_value_create_nint_constant( 7823 func, jit_type_nuint, ~((jit_nint) (JIT_BEST_ALIGNMENT - 1))); 7824 if(!size || !addon || !mask) 7825 { 7826 return 0; 7827 } 7828 size = jit_insn_add(func, size, addon); 7829 if(!size) 7830 { 7831 return 0; 7832 } 7833 size = jit_insn_and(func, size, mask); 7834 if(!size) 7835 { 7836 return 0; 7837 } 7838 7839 /* Allocate "size" bytes of memory from the stack */ 7840 return apply_unary(func, JIT_OP_ALLOCA, size, jit_type_void_ptr); 7841 } 7842 7843 /*@ 7844 * @deftypefun int jit_insn_move_blocks_to_end (jit_function_t @var{func}, jit_label_t @var{from_label}, jit_label_t @var{to_label}) 7845 * Move all of the blocks between @var{from_label} (inclusive) and 7846 * @var{to_label} (exclusive) to the end of the current function. 7847 * This is typically used to move the expression in a @code{while} 7848 * loop to the end of the body, where it can be executed more 7849 * efficiently. 7850 * @end deftypefun 7851 @*/ 7852 int 7853 jit_insn_move_blocks_to_end(jit_function_t func, jit_label_t from_label, 7854 jit_label_t to_label) 7855 { 7856 /* Make sure that deferred stack pops are flushed */ 7857 if(!jit_insn_flush_defer_pop(func, 0)) 7858 { 7859 return 0; 7860 } 7861 7862 /* Find the first block that needs to be moved */ 7863 jit_block_t first = jit_block_from_label(func, from_label); 7864 if(!first) 7865 { 7866 return 0; 7867 } 7868 7869 /* Find the last block that needs to be moved */ 7870 jit_block_t last = jit_block_from_label(func, to_label); 7871 if(!last) 7872 { 7873 return 0; 7874 } 7875 7876 /* Sanity check -- the last block has to be after the first */ 7877 jit_block_t block; 7878 for(block = first->next; block != last; block = block->next) 7879 { 7880 if(!block) 7881 { 7882 return 0; 7883 } 7884 } 7885 7886 /* The last block is excluded from the blocks to move */ 7887 block = last->prev; 7888 7889 /* Move the blocks to the end */ 7890 _jit_block_detach(first, block); 7891 _jit_block_attach_before(func->builder->exit_block, first, block); 7892 func->builder->current_block = block; 7893 7894 /* Create a new block after the last one we moved, to start fresh */ 7895 return jit_insn_new_block(func); 7896 } 7897 7898 /*@ 7899 * @deftypefun int jit_insn_move_blocks_to_start (jit_function_t @var{func}, jit_label_t @var{from_label}, jit_label_t @var{to_label}) 7900 * Move all of the blocks between @var{from_label} (inclusive) and 7901 * @var{to_label} (exclusive) to the start of the current function. 7902 * This is typically used to move initialization code to the head 7903 * of the function. 7904 * @end deftypefun 7905 @*/ 7906 int 7907 jit_insn_move_blocks_to_start(jit_function_t func, jit_label_t from_label, jit_label_t to_label) 7908 { 7909 /* Make sure that deferred stack pops are flushed */ 7910 if(!jit_insn_flush_defer_pop(func, 0)) 7911 { 7912 return 0; 7913 } 7914 7915 /* Find the first block that needs to be moved */ 7916 jit_block_t first = jit_block_from_label(func, from_label); 7917 if(!first) 7918 { 7919 return 0; 7920 } 7921 7922 /* Find the last block that needs to be moved */ 7923 jit_block_t last = jit_block_from_label(func, to_label); 7924 if(!last) 7925 { 7926 return 0; 7927 } 7928 7929 /* Init block */ 7930 jit_block_t init = func->builder->init_block; 7931 7932 /* Sanity check -- the first block has to be after the init */ 7933 jit_block_t block; 7934 for(block = init->next; block != first; block = block->next) 7935 { 7936 if(!block) 7937 { 7938 return 0; 7939 } 7940 } 7941 /* Sanity check -- the last block has to be after the first */ 7942 for(block = first->next; block != last; block = block->next) 7943 { 7944 if(!block) 7945 { 7946 return 0; 7947 } 7948 } 7949 7950 /* The last block is excluded from the blocks to move */ 7951 block = last->prev; 7952 7953 /* Update the init block pointer */ 7954 func->builder->init_block = block; 7955 7956 /* Move the blocks after the original init block */ 7957 if(init->next != first) 7958 { 7959 _jit_block_detach(first, block); 7960 _jit_block_attach_after(init, first, block); 7961 } 7962 7963 /* Done */ 7964 return 1; 7965 } 7966 7967 /*@ 7968 * @deftypefun int jit_insn_mark_offset (jit_function_t @var{func}, jit_int @var{offset}) 7969 * Mark the current position in @var{func} as corresponding to the 7970 * specified bytecode @var{offset}. This value will be returned 7971 * by @code{jit_stack_trace_get_offset}, and is useful for associating 7972 * code positions with source line numbers. 7973 * @end deftypefun 7974 @*/ 7975 int 7976 jit_insn_mark_offset(jit_function_t func, jit_int offset) 7977 { 7978 /* Ensure that we have a builder for this function */ 7979 if(!_jit_function_ensure_builder(func)) 7980 { 7981 return 0; 7982 } 7983 7984 jit_value_t value = jit_value_create_nint_constant(func, jit_type_int, offset); 7985 if(!value) 7986 { 7987 return 0; 7988 } 7989 7990 /* If the previous instruction is mark offset too 7991 then just replace the offset value in place -- 7992 we are not interested in bytecodes that produce 7993 no real code. */ 7994 jit_block_t block = func->builder->current_block; 7995 jit_insn_t last = _jit_block_get_last(block); 7996 if(last && last->opcode == JIT_OP_MARK_OFFSET) 7997 { 7998 last->value1 = value; 7999 return 1; 8000 } 8001 8002 return create_unary_note(func, JIT_OP_MARK_OFFSET, value); 8003 } 8004 8005 /* Documentation is in jit-debugger.c */ 8006 int 8007 jit_insn_mark_breakpoint_variable(jit_function_t func, jit_value_t data1, jit_value_t data2) 8008 { 8009 #if defined(JIT_BACKEND_INTERP) 8010 /* Use the "mark_breakpoint" instruction for the interpreter */ 8011 if(!jit_insn_new_block(func)) 8012 { 8013 return 0; 8014 } 8015 return create_note(func, JIT_OP_MARK_BREAKPOINT, data1, data2); 8016 #else 8017 /* Insert a call to "_jit_debugger_hook" on native platforms */ 8018 jit_type_t params[3]; 8019 jit_type_t signature; 8020 jit_value_t values[3]; 8021 params[0] = jit_type_void_ptr; 8022 params[1] = jit_type_nint; 8023 params[2] = jit_type_nint; 8024 signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 3, 0); 8025 if(!signature) 8026 { 8027 return 0; 8028 } 8029 values[0] = jit_value_create_nint_constant(func, jit_type_void_ptr, (jit_nint) func); 8030 if(!values[0]) 8031 { 8032 jit_type_free(signature); 8033 return 0; 8034 } 8035 values[1] = data1; 8036 values[2] = data2; 8037 jit_insn_call_native(func, "_jit_debugger_hook", (void *) _jit_debugger_hook, 8038 signature, values, 3, JIT_CALL_NOTHROW); 8039 jit_type_free(signature); 8040 return 1; 8041 #endif 8042 } 8043 8044 /* Documentation is in jit-debugger.c */ 8045 int 8046 jit_insn_mark_breakpoint(jit_function_t func, jit_nint data1, jit_nint data2) 8047 { 8048 jit_value_t value1; 8049 jit_value_t value2; 8050 8051 value1 = jit_value_create_nint_constant(func, jit_type_nint, data1); 8052 value2 = jit_value_create_nint_constant(func, jit_type_nint, data2); 8053 if(!value1 || !value2) 8054 { 8055 return 0; 8056 } 8057 8058 return jit_insn_mark_breakpoint_variable(func, value1, value2); 8059 } 8060 8061 /*@ 8062 * @deftypefun void jit_insn_iter_init (jit_insn_iter_t *@var{iter}, jit_block_t @var{block}) 8063 * Initialize an iterator to point to the first instruction in @var{block}. 8064 * @end deftypefun 8065 @*/ 8066 void 8067 jit_insn_iter_init(jit_insn_iter_t *iter, jit_block_t block) 8068 { 8069 iter->block = block; 8070 iter->posn = 0; 8071 } 8072 8073 /*@ 8074 * @deftypefun void jit_insn_iter_init_last (jit_insn_iter_t *@var{iter}, jit_block_t @var{block}) 8075 * Initialize an iterator to point to the last instruction in @var{block}. 8076 * @end deftypefun 8077 @*/ 8078 void 8079 jit_insn_iter_init_last(jit_insn_iter_t *iter, jit_block_t block) 8080 { 8081 iter->block = block; 8082 iter->posn = block->num_insns; 8083 } 8084 8085 /*@ 8086 * @deftypefun jit_insn_t jit_insn_iter_next (jit_insn_iter_t *@var{iter}) 8087 * Get the next instruction in an iterator's block. Returns NULL 8088 * when there are no further instructions in the block. 8089 * @end deftypefun 8090 @*/ 8091 jit_insn_t 8092 jit_insn_iter_next(jit_insn_iter_t *iter) 8093 { 8094 if(iter->posn < iter->block->num_insns) 8095 { 8096 return &iter->block->insns[iter->posn++]; 8097 } 8098 else 8099 { 8100 return 0; 8101 } 8102 } 8103 8104 /*@ 8105 * @deftypefun jit_insn_t jit_insn_iter_previous (jit_insn_iter_t *@var{iter}) 8106 * Get the previous instruction in an iterator's block. Returns NULL 8107 * when there are no further instructions in the block. 8108 * @end deftypefun 8109 @*/ 8110 jit_insn_t 8111 jit_insn_iter_previous(jit_insn_iter_t *iter) 8112 { 8113 if(iter->posn > 0) 8114 { 8115 return &iter->block->insns[--iter->posn]; 8116 } 8117 else 8118 { 8119 return 0; 8120 } 8121 }