github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-reg-alloc.c (about) 1 /* 2 * jit-reg-alloc.c - Register allocation routines for the JIT. 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-reg-alloc.h" 25 #include <jit/jit-dump.h> 26 #include <stdio.h> 27 #include <string.h> 28 29 /*@ 30 31 The @code{libjit} library provides a number of functions for 32 performing register allocation within basic blocks so that you 33 mostly don't have to worry about it: 34 35 @*/ 36 37 /* 38 * Dump debug information about the register allocation state. 39 */ 40 #undef JIT_REG_DEBUG 41 42 /* 43 * Minimum number of times a candidate must be used before it 44 * is considered worthy of putting in a global register. 45 */ 46 #define JIT_MIN_USED 3 47 48 /* 49 * Use is_register_occupied() function. 50 */ 51 #undef IS_REGISTER_OCCUPIED 52 53 /* 54 * Check if the register is on the register stack. 55 */ 56 #ifdef JIT_REG_STACK 57 #define IS_STACK_REG(reg) ((jit_reg_flags(reg) & JIT_REG_IN_STACK) != 0) 58 #else 59 #define IS_STACK_REG(reg) (0) 60 #endif 61 62 /* The cost value that precludes using the register in question. */ 63 #define COST_TOO_MUCH 1000000 64 65 #define COST_COPY 4 66 #define COST_SPILL_DIRTY 16 67 #define COST_SPILL_DIRTY_GLOBAL 4 68 #define COST_SPILL_CLEAN 1 69 #define COST_SPILL_CLEAN_GLOBAL 1 70 #define COST_GLOBAL_BIAS 2 71 #define COST_THRASH 100 72 #define COST_CLOBBER_GLOBAL 1000 73 74 #ifdef JIT_BACKEND_X86 75 # define ALLOW_CLOBBER_GLOBAL 1 76 #else 77 # define ALLOW_CLOBBER_GLOBAL 0 78 #endif 79 80 /* Value usage flags. */ 81 #define VALUE_INPUT 1 82 #define VALUE_USED 2 83 #define VALUE_LIVE 4 84 #define VALUE_DEAD 8 85 86 /* Clobber flags. */ 87 #define CLOBBER_NONE 0 88 #define CLOBBER_INPUT_VALUE 1 89 #define CLOBBER_REG 2 90 #define CLOBBER_OTHER_REG 4 91 92 #ifdef JIT_REG_DEBUG 93 #include <stdlib.h> 94 95 static void dump_regs(jit_gencode_t gen, const char *name) 96 { 97 int reg, index; 98 jit_value_t value; 99 100 printf("%s:\n", name); 101 for(reg = 0; reg < JIT_NUM_REGS; ++reg) 102 { 103 if(gen->contents[reg].num_values == 0 && !(gen->contents[reg].used_for_temp)) 104 { 105 continue; 106 } 107 printf("\t%s: ", jit_reg_name(reg)); 108 if(gen->contents[reg].num_values > 0) 109 { 110 for(index = 0; index < gen->contents[reg].num_values; ++index) 111 { 112 value = gen->contents[reg].values[index]; 113 if(index) 114 { 115 fputs(", ", stdout); 116 } 117 jit_dump_value(stdout, jit_value_get_function(value), value, 0); 118 } 119 if(gen->contents[reg].used_for_temp) 120 { 121 printf(", used_for_temp"); 122 } 123 } 124 else if(gen->contents[reg].used_for_temp) 125 { 126 printf("used_for_temp"); 127 } 128 else 129 { 130 printf("free"); 131 } 132 putc('\n', stdout); 133 } 134 #ifdef JIT_REG_STACK 135 printf("stack_top: %d\n", gen->reg_stack_top); 136 #endif 137 fflush(stdout); 138 } 139 #endif 140 141 /* 142 * Find the start register of a register pair given the end register. 143 */ 144 static int 145 get_long_pair_start(int other_reg) 146 { 147 int reg; 148 for(reg = 0; reg < JIT_NUM_REGS; reg++) 149 { 150 if(other_reg == jit_reg_other_reg(reg)) 151 { 152 return reg; 153 } 154 } 155 return -1; 156 } 157 158 /* 159 * Check if two values are known to be equal. 160 */ 161 static int 162 are_values_equal(_jit_regdesc_t *desc1, _jit_regdesc_t *desc2) 163 { 164 if(desc1 && desc2 && desc1->value && desc2->value) 165 { 166 if(desc1->value == desc2->value) 167 { 168 return 1; 169 } 170 if(desc1->value->in_register && desc2->value->in_register) 171 { 172 return desc1->value->reg == desc2->value->reg; 173 } 174 } 175 return 0; 176 } 177 178 /* 179 * Exchange the content of two value descriptors. 180 */ 181 static void 182 swap_values(_jit_regdesc_t *desc1, _jit_regdesc_t *desc2) 183 { 184 _jit_regdesc_t tdesc; 185 tdesc = *desc1; 186 *desc1 = *desc2; 187 *desc2 = tdesc; 188 } 189 190 /* 191 * Get value usage and liveness information. The accurate liveness data is 192 * only available for values used by the current instruction. 193 * 194 * VALUE_INPUT flag is set if the value is one of the instruction's inputs. 195 * 196 * VALUE_LIVE and VALUE_USED flags are set for input values only according 197 * to the liveness flags provided along with the instruction. 198 * 199 * VALUE_DEAD flag is set in two cases. First, it is always set for output 200 * values. Second, it is set for input values that are neither live nor used. 201 * 202 * These flags are used when spilling a register. In this case we generally 203 * do not know if the values in the register are used by the instruction. If 204 * the VALUE_INPUT flag is present then it is so and the value has to be held 205 * in the register for the instruction to succeed. If the VALUE_DEAD flag is 206 * present then there is no need to spill the value and it may be discarded. 207 * Otherwise the value must be spilled. 208 * 209 * The VALUE_LIVE and VALUE_USED flags may only be set for input values of 210 * the instruction. For other values these flags are not set even if they are 211 * perfectly alive. These flags are used as a hint for spill cost calculation. 212 * 213 * NOTE: The output value is considered to be dead because the instruction is 214 * just about to recompute it so there is no point to save it. 215 * 216 * Generally, a value becomes dead just after the instruction that used it 217 * last time. The allocator frees dead values after each instruction so it 218 * might seem that there is no chance to find any dead value on the current 219 * instruction. However if the value is used by the current instruction both 220 * as the input and output then it was alive after the last instruction and 221 * hence was not freed. And just in case if some dead values may creep through 222 * the allocator's checks... 223 */ 224 static int 225 value_usage(_jit_regs_t *regs, jit_value_t value) 226 { 227 int flags; 228 229 flags = 0; 230 if(value->is_constant) 231 { 232 flags |= VALUE_DEAD; 233 } 234 if(!regs) 235 { 236 return flags; 237 } 238 if(value == regs->descs[0].value) 239 { 240 if(regs->ternary) 241 { 242 flags |= VALUE_INPUT; 243 if(regs->descs[0].used) 244 { 245 flags |= VALUE_LIVE | VALUE_USED; 246 } 247 else if(regs->descs[0].live) 248 { 249 flags |= VALUE_LIVE; 250 } 251 else 252 { 253 flags |= VALUE_DEAD; 254 } 255 } 256 else 257 { 258 flags |= VALUE_DEAD; 259 } 260 } 261 if(value == regs->descs[1].value) 262 { 263 flags |= VALUE_INPUT; 264 if(regs->descs[1].used) 265 { 266 flags |= VALUE_LIVE | VALUE_USED; 267 } 268 else if(regs->descs[1].live) 269 { 270 flags |= VALUE_LIVE; 271 } 272 else 273 { 274 flags |= VALUE_DEAD; 275 } 276 } 277 if(value == regs->descs[2].value) 278 { 279 flags |= VALUE_INPUT; 280 if(regs->descs[2].used) 281 { 282 flags |= VALUE_LIVE | VALUE_USED; 283 } 284 else if(regs->descs[2].live) 285 { 286 flags |= VALUE_LIVE; 287 } 288 else 289 { 290 flags |= VALUE_DEAD; 291 } 292 } 293 return flags; 294 } 295 296 /* 297 * Check if the register contains any live values. 298 */ 299 static int 300 is_register_alive(jit_gencode_t gen, _jit_regs_t *regs, int reg) 301 { 302 int index, usage; 303 304 if(reg < 0) 305 { 306 return 0; 307 } 308 309 /* Assume that a global register is always alive unless it is to be 310 computed right away. */ 311 if(jit_reg_is_used(gen->permanent, reg)) 312 { 313 if(!regs->ternary 314 && regs->descs[0].value 315 && regs->descs[0].value->has_global_register 316 && regs->descs[0].value->global_reg == reg) 317 { 318 return 0; 319 } 320 return 1; 321 } 322 323 if(gen->contents[reg].is_long_end) 324 { 325 reg = get_long_pair_start(reg); 326 } 327 for(index = 0; index < gen->contents[reg].num_values; index++) 328 { 329 usage = value_usage(regs, gen->contents[reg].values[index]); 330 if((usage & VALUE_DEAD) == 0) 331 { 332 return 1; 333 } 334 } 335 336 return 0; 337 } 338 339 #ifdef IS_REGISTER_OCCUPIED 340 /* 341 * Check if the register contains any values either dead or alive 342 * that may need to be evicted from it. 343 */ 344 static int 345 is_register_occupied(jit_gencode_t gen, _jit_regs_t *regs, int reg) 346 { 347 if(reg < 0) 348 { 349 return 0; 350 } 351 352 /* Assume that a global register is always occupied. */ 353 if(jit_reg_is_used(gen->permanent, reg)) 354 { 355 return 1; 356 } 357 358 if(gen->contents[reg].is_long_end) 359 { 360 reg = get_long_pair_start(reg); 361 } 362 if(gen->contents[reg].num_values) 363 { 364 return 1; 365 } 366 367 return 0; 368 } 369 #endif 370 371 /* 372 * Determine the effect of using a register for a value. This includes the 373 * following: 374 * - whether the value is clobbered by the instruction; 375 * - whether the previous contents of the register is clobbered. 376 * 377 * The value is clobbered by the instruction if it is used as input value 378 * and the output value will go to the same register and these two values 379 * are not equal. Or the instruction has a side effect that destroys the 380 * input value regardless of the output. This is indicated with the 381 * CLOBBER_INPUT_VALUE flag. 382 * 383 * The previous content is clobbered if the register contains any non-dead 384 * values that are destroyed by loading the input value, by computing the 385 * output value, or as a side effect of the instruction. 386 * 387 * The previous content is not clobbered if the register contains only dead 388 * values or it is used for input value that is already in the register so 389 * there is no need to load it and at the same time the instruction has no 390 * side effects that destroy the input value or the register is used for 391 * output value and the only value it contained before is the same value. 392 * 393 * The flag CLOBBER_REG indicates if the previous content of the register is 394 * clobbered. The flag CLOBBER_OTHER_REG indicates that the other register 395 * in a long pair is clobbered. 396 * 397 */ 398 static int 399 clobbers_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, int other_reg) 400 { 401 int flags; 402 403 if(!regs->descs[index].value) 404 { 405 return CLOBBER_NONE; 406 } 407 408 if(regs->ternary || !regs->descs[0].value) 409 { 410 /* this is either a ternary or binary or unary note */ 411 if(regs->descs[index].clobber) 412 { 413 flags = CLOBBER_INPUT_VALUE; 414 } 415 #ifdef JIT_REG_STACK 416 else if(IS_STACK_REG(reg) && !regs->no_pop) 417 { 418 flags = CLOBBER_INPUT_VALUE; 419 } 420 #endif 421 else 422 { 423 flags = CLOBBER_NONE; 424 } 425 } 426 else if(index == 0) 427 { 428 /* this is the output value of a binary or unary op */ 429 430 /* special case: a copy operation. Check if we could coalesce 431 the destination value with the source. */ 432 if(regs->copy 433 && regs->descs[1].value 434 && regs->descs[1].value->in_register 435 && regs->descs[1].value->reg == reg 436 && ((regs->descs[0].value->in_register && regs->descs[0].value->reg == reg) 437 || gen->contents[reg].num_values < JIT_MAX_REG_VALUES 438 || !(regs->descs[1].used || regs->descs[1].live))) 439 { 440 return CLOBBER_NONE; 441 } 442 443 flags = CLOBBER_NONE; 444 #ifdef IS_REGISTER_OCCUPIED 445 if(is_register_occupied(gen, regs, reg)) 446 { 447 flags |= CLOBBER_REG; 448 } 449 if(is_register_occupied(gen, regs, other_reg)) 450 { 451 flags |= CLOBBER_OTHER_REG; 452 } 453 #else 454 if(is_register_alive(gen, regs, reg)) 455 { 456 flags |= CLOBBER_REG; 457 } 458 if(is_register_alive(gen, regs, other_reg)) 459 { 460 flags |= CLOBBER_OTHER_REG; 461 } 462 #endif 463 return flags; 464 } 465 else if(regs->copy) 466 { 467 flags = CLOBBER_NONE; 468 } 469 #ifdef JIT_REG_STACK 470 else if(IS_STACK_REG(reg) && !regs->no_pop) 471 { 472 /* this is a binary or unary stack op -- the input value 473 is either popped or overwritten by the output */ 474 flags = CLOBBER_INPUT_VALUE; 475 } 476 #endif 477 else if(reg == regs->descs[0].reg 478 || reg == regs->descs[0].other_reg 479 || other_reg == regs->descs[0].reg) 480 { 481 /* the input value of a binary or unary op is clobbered 482 by the output value */ 483 flags = CLOBBER_INPUT_VALUE; 484 } 485 else if(regs->descs[index].clobber) 486 { 487 flags = CLOBBER_INPUT_VALUE; 488 } 489 else 490 { 491 flags = CLOBBER_NONE; 492 } 493 494 if(flags == CLOBBER_NONE) 495 { 496 if(regs->descs[index].value->has_global_register 497 && regs->descs[index].value->global_reg == reg) 498 { 499 return CLOBBER_NONE; 500 } 501 if(regs->descs[index].value->in_register 502 && regs->descs[index].value->reg == reg) 503 { 504 return CLOBBER_NONE; 505 } 506 } 507 508 #ifdef IS_REGISTER_OCCUPIED 509 if(is_register_occupied(gen, regs, reg)) 510 { 511 flags |= CLOBBER_REG; 512 } 513 if(is_register_occupied(gen, regs, other_reg)) 514 { 515 flags |= CLOBBER_OTHER_REG; 516 } 517 #else 518 if(is_register_alive(gen, regs, reg)) 519 { 520 flags |= CLOBBER_REG; 521 } 522 if(is_register_alive(gen, regs, other_reg)) 523 { 524 flags |= CLOBBER_OTHER_REG; 525 } 526 #endif 527 return flags; 528 } 529 530 /* 531 * Assign scratch register. 532 */ 533 static void 534 set_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg) 535 { 536 if(reg >= 0) 537 { 538 regs->scratch[index].reg = reg; 539 540 jit_reg_set_used(gen->touched, reg); 541 jit_reg_set_used(regs->clobber, reg); 542 jit_reg_set_used(regs->assigned, reg); 543 } 544 } 545 546 /* 547 * Set value information. 548 */ 549 static void 550 set_regdesc_value( 551 _jit_regs_t *regs, 552 int index, 553 jit_value_t value, 554 int flags, 555 _jit_regclass_t *regclass, 556 int live, 557 int used) 558 { 559 _jit_regdesc_t *desc; 560 561 desc = ®s->descs[index]; 562 desc->value = value; 563 desc->clobber = ((flags & (_JIT_REGS_CLOBBER | _JIT_REGS_EARLY_CLOBBER)) != 0); 564 desc->early_clobber = ((flags & _JIT_REGS_EARLY_CLOBBER) != 0); 565 desc->regclass = regclass; 566 desc->live = live; 567 desc->used = used; 568 } 569 570 /* 571 * Assign register to a value. 572 */ 573 static void 574 set_regdesc_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, int other_reg) 575 { 576 int assign; 577 if(reg >= 0) 578 { 579 assign = (index > 0 || regs->ternary || regs->descs[0].early_clobber); 580 581 regs->descs[index].reg = reg; 582 regs->descs[index].other_reg = other_reg; 583 584 jit_reg_set_used(gen->touched, reg); 585 if(assign) 586 { 587 jit_reg_set_used(regs->assigned, reg); 588 } 589 if(other_reg >= 0) 590 { 591 jit_reg_set_used(gen->touched, other_reg); 592 if(assign) 593 { 594 jit_reg_set_used(regs->assigned, other_reg); 595 } 596 } 597 } 598 } 599 600 /* 601 * Determine value flags. 602 */ 603 static void 604 set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) 605 { 606 _jit_regdesc_t *desc; 607 int reg, other_reg; 608 int clobber, clobber_input; 609 int is_input, is_live_input, is_used_input; 610 611 #ifdef JIT_REG_DEBUG 612 printf("set_regdesc_flags(index = %d)\n", index); 613 #endif 614 615 desc = ®s->descs[index]; 616 if(desc->reg < 0 || desc->duplicate) 617 { 618 return; 619 } 620 621 /* See if the value clobbers the register it is assigned to. */ 622 clobber = clobbers_register(gen, regs, index, desc->reg, desc->other_reg); 623 #ifdef JIT_REG_DEBUG 624 if((clobber & CLOBBER_INPUT_VALUE) != 0) 625 { 626 printf("clobber input\n"); 627 } 628 if((clobber & CLOBBER_REG) != 0) 629 { 630 printf("clobber reg\n"); 631 } 632 if((clobber & CLOBBER_OTHER_REG) != 0) 633 { 634 printf("clobber other reg\n"); 635 } 636 #endif 637 638 /* See if this is an input value and whether it is alive. */ 639 if(regs->ternary) 640 { 641 is_input = 1; 642 is_live_input = desc->live; 643 is_used_input = desc->used; 644 } 645 else if(index > 0) 646 { 647 is_input = 1; 648 if(regs->descs[0].value == desc->value) 649 { 650 is_live_input = is_used_input = 0; 651 } 652 else 653 { 654 is_live_input = desc->live; 655 is_used_input = desc->used; 656 } 657 } 658 else 659 { 660 is_input = is_live_input = is_used_input = 0; 661 } 662 663 if(is_input) 664 { 665 /* Find the register the value is already in (if any). */ 666 if(desc->value->in_register) 667 { 668 reg = desc->value->reg; 669 if(gen->contents[reg].is_long_start) 670 { 671 other_reg = jit_reg_other_reg(reg); 672 } 673 else 674 { 675 other_reg = -1; 676 } 677 } 678 else 679 { 680 reg = -1; 681 other_reg = -1; 682 } 683 684 /* See if the input value is thrashed by other inputs. The allocator 685 tries to avoid thrashing so it may only take place if the register 686 is assigned explicitly. For x87 registers the problem of thrashing 687 may be best solved with fxch but as the stack registers are never 688 assigned explicitely there is no such problem for them at all. */ 689 if(reg >= 0) 690 { 691 if(index != 0 && regs->ternary 692 && !are_values_equal(desc, ®s->descs[0])) 693 { 694 if(reg == regs->descs[0].reg 695 || reg == regs->descs[0].other_reg 696 || (other_reg >= 0 697 && (other_reg == regs->descs[0].reg 698 || other_reg == regs->descs[0].other_reg))) 699 { 700 desc->thrash = 1; 701 } 702 } 703 if(index != 1 && !are_values_equal(desc, ®s->descs[1])) 704 { 705 if(reg == regs->descs[1].reg 706 || reg == regs->descs[1].other_reg 707 || (other_reg >= 0 708 && (other_reg == regs->descs[1].reg 709 || other_reg == regs->descs[1].other_reg))) 710 { 711 desc->thrash = 1; 712 } 713 } 714 if(index != 2 && !are_values_equal(desc, ®s->descs[2])) 715 { 716 if(reg == regs->descs[2].reg 717 || reg == regs->descs[2].other_reg 718 || (other_reg >= 0 719 && (other_reg == regs->descs[2].reg 720 || other_reg == regs->descs[2].other_reg))) 721 { 722 desc->thrash = 1; 723 } 724 } 725 726 if(desc->thrash) 727 { 728 reg = -1; 729 other_reg = -1; 730 } 731 } 732 733 /* See if the value needs to be loaded or copied or none. */ 734 if(reg != desc->reg) 735 { 736 if(desc->value->has_global_register) 737 { 738 desc->copy = (desc->value->global_reg != desc->reg); 739 } 740 else if(reg < 0) 741 { 742 desc->load = 1; 743 } 744 else 745 { 746 desc->copy = 1; 747 } 748 } 749 750 /* See if the input value needs to be stored before the 751 instruction and if it stays in the register after it. */ 752 if(desc->value->is_constant) 753 { 754 desc->kill = 1; 755 } 756 else if(!is_used_input) 757 { 758 desc->store = is_live_input; 759 desc->kill = 1; 760 } 761 else 762 { 763 /* See if the input value is destroyed by the instruction. */ 764 clobber_input = 0; 765 if(!desc->copy) 766 { 767 if(jit_reg_is_used(regs->clobber, desc->reg) 768 || (desc->other_reg >= 0 769 && jit_reg_is_used(regs->clobber, desc->other_reg))) 770 { 771 clobber_input = 1; 772 } 773 else if ((clobber & CLOBBER_INPUT_VALUE) != 0) 774 { 775 clobber_input = 1; 776 } 777 } 778 else if(reg >= 0) 779 { 780 if(jit_reg_is_used(regs->clobber, reg) 781 || (other_reg >= 0 782 && jit_reg_is_used(regs->clobber, other_reg))) 783 { 784 clobber_input = 1; 785 } 786 else if(!regs->ternary 787 && regs->descs[0].value 788 && (reg == regs->descs[0].reg 789 || reg == regs->descs[0].other_reg 790 || other_reg == regs->descs[0].reg)) 791 { 792 clobber_input = 1; 793 } 794 } 795 796 if(clobber_input) 797 { 798 desc->store = 1; 799 desc->kill = 1; 800 } 801 } 802 803 /* Store the value if it is going to be thrashed by another one. */ 804 if(desc->thrash) 805 { 806 desc->store = 1; 807 } 808 809 #ifdef JIT_REG_STACK 810 /* Count stack registers. */ 811 if(IS_STACK_REG(desc->reg)) 812 { 813 ++(regs->wanted_stack_count); 814 if(!desc->load && !desc->copy) 815 { 816 ++(regs->loaded_stack_count); 817 } 818 } 819 #endif 820 } 821 822 /* See if the value clobbers a global register. In this case the global 823 register is pushed onto stack before the instruction and popped back 824 after it. */ 825 if(!desc->copy 826 && (!desc->value->has_global_register || desc->value->global_reg != desc->reg) 827 && (jit_reg_is_used(gen->permanent, desc->reg) 828 || (desc->other_reg >= 0 && jit_reg_is_used(gen->permanent, desc->other_reg)))) 829 { 830 desc->kill = 1; 831 } 832 833 /* Set clobber flags (this indicates registers to be spilled). */ 834 if((clobber & CLOBBER_REG) != 0) 835 { 836 jit_reg_set_used(regs->clobber, desc->reg); 837 } 838 if((clobber & CLOBBER_OTHER_REG) != 0) 839 { 840 jit_reg_set_used(regs->clobber, desc->other_reg); 841 } 842 843 #ifdef JIT_REG_DEBUG 844 printf("value = "); 845 jit_dump_value(stdout, jit_value_get_function(desc->value), desc->value, 0); 846 printf("\n"); 847 printf("value->in_register = %d\n", desc->value->in_register); 848 printf("value->reg = %d\n", desc->value->reg); 849 printf("value->has_global_register = %d\n", desc->value->has_global_register); 850 printf("value->in_global_register = %d\n", desc->value->in_global_register); 851 printf("value->global_reg = %d\n", desc->value->global_reg); 852 printf("value->in_frame = %d\n", desc->value->in_frame); 853 printf("reg = %d\n", desc->reg); 854 printf("other_reg = %d\n", desc->other_reg); 855 printf("live = %d\n", desc->live); 856 printf("used = %d\n", desc->used); 857 printf("clobber = %d\n", desc->clobber); 858 printf("early_clobber = %d\n", desc->early_clobber); 859 printf("duplicate = %d\n", desc->duplicate); 860 printf("thrash = %d\n", desc->thrash); 861 printf("store = %d\n", desc->store); 862 printf("load = %d\n", desc->load); 863 printf("copy = %d\n", desc->copy); 864 printf("kill = %d\n", desc->kill); 865 #endif 866 } 867 868 /* 869 * Compute the register spill cost. The register spill cost is computed as 870 * the sum of spill costs of individual values the register contains. The 871 * spill cost of a value depends on the following factors: 872 * 873 * 1. Values that are not used after the current instruction may be safely 874 * discareded so their spill cost is taken to be zero. 875 * 2. Values that are spilled to global registers are cheaper than values 876 * that are spilled into stack frame. 877 * 3. Clean values are cheaper than dirty values. 878 * 879 * NOTE: A value is clean if it was loaded from the stack frame or from a 880 * global register and has not changed since then. Otherwise it is dirty. 881 * There is no need to spill clean values. However their spill cost is 882 * considered to be non-zero so that the register allocator will choose 883 * those registers that do not contain live values over those that contain 884 * live albeit clean values. 885 * 886 * For global registers this function returns the cost of zero. So global 887 * registers have to be handled separately. 888 */ 889 static int 890 compute_spill_cost(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg) 891 { 892 int cost, index, usage; 893 jit_value_t value; 894 895 if(gen->contents[reg].is_long_end) 896 { 897 reg = get_long_pair_start(reg); 898 } 899 900 cost = 0; 901 for(index = 0; index < gen->contents[reg].num_values; index++) 902 { 903 value = gen->contents[reg].values[index]; 904 usage = value_usage(regs, value); 905 if((usage & VALUE_DEAD) != 0) 906 { 907 /* the value is not spilled */ 908 continue; 909 } 910 if((usage & VALUE_LIVE) != 0 && (usage & VALUE_USED) == 0) 911 { 912 /* the value has to be spilled anyway */ 913 /* NOTE: This is true for local register allocation, 914 review for future global allocator. */ 915 continue; 916 } 917 if(value->has_global_register) 918 { 919 if(value->in_global_register) 920 { 921 cost += COST_SPILL_CLEAN_GLOBAL; 922 } 923 else 924 { 925 cost += COST_SPILL_DIRTY_GLOBAL; 926 } 927 } 928 else 929 { 930 if(value->in_frame) 931 { 932 cost += COST_SPILL_CLEAN; 933 } 934 else 935 { 936 cost += COST_SPILL_DIRTY; 937 } 938 } 939 } 940 941 if(gen->contents[reg].is_long_start) 942 { 943 return cost * 2; 944 } 945 946 if(other_reg >= 0) 947 { 948 for(index = 0; index < gen->contents[other_reg].num_values; index++) 949 { 950 value = gen->contents[other_reg].values[index]; 951 usage = value_usage(regs, value); 952 if((usage & VALUE_DEAD) != 0) 953 { 954 /* the value is not spilled */ 955 continue; 956 } 957 if((usage & VALUE_LIVE) != 0 && (usage & VALUE_USED) == 0) 958 { 959 /* the value has to be spilled anyway */ 960 /* NOTE: This is true for local register allocation, 961 review for future global allocator. */ 962 continue; 963 } 964 if(value->has_global_register) 965 { 966 if(value->in_global_register) 967 { 968 cost += COST_SPILL_CLEAN_GLOBAL; 969 } 970 else 971 { 972 cost += COST_SPILL_DIRTY_GLOBAL; 973 } 974 } 975 else 976 { 977 if(value->in_frame) 978 { 979 cost += COST_SPILL_CLEAN; 980 } 981 else 982 { 983 cost += COST_SPILL_DIRTY; 984 } 985 } 986 } 987 } 988 989 return cost; 990 } 991 992 static int 993 thrashes_value(jit_gencode_t gen, 994 _jit_regdesc_t *desc, int reg, int other_reg, 995 _jit_regdesc_t *desc2) 996 { 997 int reg2, other_reg2; 998 999 #if ALLOW_CLOBBER_GLOBAL 1000 if(desc2->value->has_global_register) 1001 { 1002 if(desc2->value->global_reg == reg) 1003 { 1004 if(desc && desc2->value == desc->value) 1005 { 1006 return 0; 1007 } 1008 return 1; 1009 } 1010 if(desc2->value->global_reg == other_reg) 1011 { 1012 return 1; 1013 } 1014 } 1015 #endif 1016 1017 if(desc2->value->in_register) 1018 { 1019 reg2 = desc2->value->reg; 1020 if(reg2 == reg) 1021 { 1022 if(are_values_equal(desc2, desc)) 1023 { 1024 return 0; 1025 } 1026 return 1; 1027 } 1028 if(reg2 == other_reg) 1029 { 1030 return 1; 1031 } 1032 if(gen->contents[reg2].is_long_start) 1033 { 1034 other_reg2 = jit_reg_other_reg(reg2); 1035 if(other_reg2 == reg /*|| other_reg2 == other_reg*/) 1036 { 1037 return 1; 1038 } 1039 } 1040 } 1041 1042 return 0; 1043 } 1044 1045 static void 1046 choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index) 1047 { 1048 _jit_regclass_t *regclass; 1049 int reg_index, reg; 1050 int use_cost; 1051 int suitable_reg; 1052 int suitable_cost; 1053 int suitable_age; 1054 1055 #ifdef JIT_REG_DEBUG 1056 printf("choose_scratch_register(%d)\n", index); 1057 #endif 1058 1059 regclass = regs->scratch[index].regclass; 1060 1061 suitable_reg = -1; 1062 suitable_cost = COST_TOO_MUCH; 1063 suitable_age = -1; 1064 for(reg_index = 0; reg_index < regclass->num_regs; reg_index++) 1065 { 1066 reg = regclass->regs[reg_index]; 1067 if(jit_reg_is_used(regs->assigned, reg)) 1068 { 1069 continue; 1070 } 1071 1072 if(jit_reg_is_used(gen->permanent, reg)) 1073 { 1074 #if ALLOW_CLOBBER_GLOBAL 1075 use_cost = COST_CLOBBER_GLOBAL; 1076 #else 1077 continue; 1078 #endif 1079 } 1080 else 1081 { 1082 use_cost = 0; 1083 } 1084 1085 #if 0 1086 if(regs->ternary && regs->descs[0].value 1087 && thrashes_value(gen, 0, reg, -1, ®s->descs[0])) 1088 { 1089 use_cost += COST_THRASH; 1090 } 1091 else if(regs->descs[1].value 1092 && thrashes_value(gen, 0, reg, -1, ®s->descs[1])) 1093 { 1094 use_cost += COST_THRASH; 1095 } 1096 else if(regs->descs[2].value 1097 && thrashes_value(gen, 0, reg, -1, ®s->descs[2])) 1098 { 1099 use_cost += COST_THRASH; 1100 } 1101 #endif 1102 1103 if(!jit_reg_is_used(regs->clobber, reg)) 1104 { 1105 use_cost += compute_spill_cost(gen, regs, reg, -1); 1106 } 1107 1108 #ifdef JIT_REG_DEBUG 1109 printf("reg = %d, use_cost = %d\n", reg, use_cost); 1110 #endif 1111 1112 if(use_cost < suitable_cost 1113 || (use_cost == suitable_cost 1114 && gen->contents[reg].num_values > 0 1115 && (IS_STACK_REG(reg) 1116 || gen->contents[reg].age < suitable_age))) 1117 { 1118 suitable_reg = reg; 1119 suitable_cost = use_cost; 1120 suitable_age = gen->contents[reg].age; 1121 } 1122 } 1123 1124 if(suitable_reg >= 0) 1125 { 1126 set_scratch_register(gen, regs, index, suitable_reg); 1127 } 1128 else 1129 { 1130 jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); 1131 } 1132 } 1133 1134 static void 1135 choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) 1136 { 1137 _jit_regclass_t *regclass; 1138 int assigned_inreg1, assigned_inreg2; 1139 int suitable_inreg1, suitable_inreg2; 1140 int reg_index, reg, other_reg; 1141 int use_cost; 1142 int suitable_reg, suitable_other_reg; 1143 int suitable_cost; 1144 int suitable_age; 1145 1146 #ifdef JIT_REG_DEBUG 1147 printf("choose_output_register()\n"); 1148 #endif 1149 1150 regclass = regs->descs[0].regclass; 1151 1152 assigned_inreg1 = suitable_inreg1 = -1; 1153 if(regs->descs[1].value) 1154 { 1155 if(regs->descs[1].reg >= 0) 1156 { 1157 assigned_inreg1 = suitable_inreg1 = regs->descs[1].reg; 1158 } 1159 else if (regs->descs[1].value->in_register) 1160 { 1161 suitable_inreg1 = regs->descs[1].value->reg; 1162 } 1163 } 1164 1165 assigned_inreg2 = suitable_inreg2 = -1; 1166 if(regs->descs[2].value) 1167 { 1168 if(regs->descs[2].reg >= 0) 1169 { 1170 assigned_inreg2 = suitable_inreg2 = regs->descs[2].reg; 1171 } 1172 else if (regs->descs[2].value->in_register) 1173 { 1174 suitable_inreg2 = regs->descs[2].value->reg; 1175 } 1176 } 1177 1178 suitable_reg = -1; 1179 suitable_other_reg = -1; 1180 suitable_cost = COST_TOO_MUCH; 1181 suitable_age = -1; 1182 for(reg_index = 0; reg_index < regclass->num_regs; reg_index++) 1183 { 1184 reg = regclass->regs[reg_index]; 1185 if(jit_reg_is_used(gen->inhibit, reg)) 1186 { 1187 continue; 1188 } 1189 1190 other_reg = jit_reg_get_pair(regs->descs[0].value->type, reg); 1191 if(other_reg >= 0 && jit_reg_is_used(gen->inhibit, other_reg)) 1192 { 1193 continue; 1194 } 1195 1196 if(jit_reg_is_used(gen->permanent, reg)) 1197 { 1198 if(!regs->descs[0].value->has_global_register 1199 || regs->descs[0].value->global_reg != reg) 1200 { 1201 /* It is not allowed to assign an output value to a global 1202 register unless it is the very value the global register 1203 contains. */ 1204 continue; 1205 } 1206 if(regs->free_dest) 1207 { 1208 if(regs->descs[0].early_clobber 1209 && regs->descs[0].value->in_global_register) 1210 { 1211 if(regs->descs[0].value == regs->descs[1].value) 1212 { 1213 continue; 1214 } 1215 if(regs->descs[0].value == regs->descs[2].value) 1216 { 1217 continue; 1218 } 1219 } 1220 use_cost = 0; 1221 } 1222 else if(regs->descs[0].value->in_global_register) 1223 { 1224 if(regs->descs[0].value == regs->descs[1].value) 1225 { 1226 use_cost = 0; 1227 } 1228 else if(regs->descs[0].value == regs->descs[2].value) 1229 { 1230 if(regs->commutative) 1231 { 1232 /* This depends on choose_input_order() 1233 doing its job on the next step. */ 1234 use_cost = 0; 1235 } 1236 else 1237 { 1238 continue; 1239 } 1240 } 1241 else 1242 { 1243 use_cost = COST_COPY; 1244 } 1245 } 1246 else 1247 { 1248 use_cost = COST_COPY; 1249 } 1250 } 1251 else 1252 { 1253 if(other_reg >= 0 && jit_reg_is_used(gen->permanent, other_reg)) 1254 { 1255 continue; 1256 } 1257 if(regs->free_dest) 1258 { 1259 if(regs->descs[0].early_clobber 1260 && (reg == suitable_inreg1 || reg == suitable_inreg2)) 1261 { 1262 continue; 1263 } 1264 use_cost = 0; 1265 } 1266 else if(reg == assigned_inreg1) 1267 { 1268 use_cost = 0; 1269 } 1270 else if(reg == assigned_inreg2) 1271 { 1272 continue; 1273 } 1274 else if(reg == suitable_inreg1) 1275 { 1276 use_cost = 0; 1277 } 1278 else if(reg == suitable_inreg2) 1279 { 1280 if(regs->commutative) 1281 { 1282 /* This depends on choose_input_order() 1283 doing its job on the next step. */ 1284 use_cost = 0; 1285 } 1286 #ifdef JIT_REG_STACK 1287 else if(regs->reversible && regs->no_pop) 1288 { 1289 /* This depends on choose_input_order() 1290 doing its job on the next step. */ 1291 use_cost = 0; 1292 } 1293 #endif 1294 else 1295 { 1296 use_cost = COST_THRASH; 1297 } 1298 } 1299 else 1300 { 1301 use_cost = COST_COPY; 1302 } 1303 if(regs->descs[0].value->has_global_register) 1304 { 1305 use_cost += COST_GLOBAL_BIAS; 1306 } 1307 } 1308 1309 if(!jit_reg_is_used(regs->clobber, reg) 1310 && !(other_reg >= 0 && jit_reg_is_used(regs->clobber, other_reg))) 1311 { 1312 use_cost += compute_spill_cost(gen, regs, reg, other_reg); 1313 } 1314 1315 #ifdef JIT_REG_DEBUG 1316 printf("reg = %d, other_reg = %d, use_cost = %d\n", reg, other_reg, use_cost); 1317 #endif 1318 1319 if(use_cost < suitable_cost 1320 || (use_cost == suitable_cost 1321 && gen->contents[reg].num_values > 0 1322 && gen->contents[reg].age < suitable_age)) 1323 { 1324 suitable_reg = reg; 1325 suitable_other_reg = other_reg; 1326 suitable_cost = use_cost; 1327 suitable_age = gen->contents[reg].age; 1328 } 1329 } 1330 1331 if(suitable_reg >= 0) 1332 { 1333 set_regdesc_register(gen, regs, 0, suitable_reg, suitable_other_reg); 1334 } 1335 else 1336 { 1337 jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); 1338 } 1339 } 1340 1341 /* 1342 * Select the best argument order for binary ops. The posibility to select 1343 * the order exists only for commutative ops and for some x87 floating point 1344 * instructions. Those x87 instructions have variants with reversed 1345 * destination register. 1346 */ 1347 static void 1348 choose_input_order(jit_gencode_t gen, _jit_regs_t *regs) 1349 { 1350 jit_value_t value; 1351 1352 value = regs->descs[2].value; 1353 if(value && value != regs->descs[1].value 1354 && ((value->in_register 1355 && value->reg == regs->descs[0].reg) 1356 || (value->in_global_register 1357 && value->global_reg == regs->descs[0].reg))) 1358 { 1359 #ifdef JIT_REG_STACK 1360 if(regs->reversible && regs->no_pop) 1361 { 1362 regs->dest_input_index = 2; 1363 } 1364 else 1365 #endif 1366 { 1367 if(regs->commutative) 1368 { 1369 swap_values(®s->descs[1], ®s->descs[2]); 1370 } 1371 regs->dest_input_index = 1; 1372 } 1373 } 1374 else if(regs->descs[1].value) 1375 { 1376 regs->dest_input_index = 1; 1377 } 1378 else 1379 { 1380 regs->dest_input_index = 0; 1381 } 1382 } 1383 1384 static void 1385 choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) 1386 { 1387 _jit_regclass_t *regclass; 1388 _jit_regdesc_t *desc; 1389 _jit_regdesc_t *desc2; 1390 int reg_index, reg, other_reg; 1391 int use_cost; 1392 int suitable_reg, suitable_other_reg; 1393 int suitable_cost; 1394 int suitable_age; 1395 int clobber; 1396 1397 #ifdef JIT_REG_DEBUG 1398 printf("choose_input_register(%d)\n", index); 1399 #endif 1400 1401 desc = ®s->descs[index]; 1402 if(!desc->value) 1403 { 1404 jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); 1405 } 1406 1407 regclass = regs->descs[index].regclass; 1408 1409 if(index == regs->dest_input_index) 1410 { 1411 desc2 = ®s->descs[0]; 1412 } 1413 else 1414 { 1415 desc2 = desc; 1416 } 1417 1418 suitable_reg = -1; 1419 suitable_other_reg = -1; 1420 suitable_cost = COST_TOO_MUCH; 1421 suitable_age = -1; 1422 for(reg_index = 0; reg_index < regclass->num_regs; reg_index++) 1423 { 1424 reg = regclass->regs[reg_index]; 1425 if(jit_reg_is_used(regs->assigned, reg)) 1426 { 1427 continue; 1428 } 1429 1430 other_reg = jit_reg_get_pair(desc->value->type, reg); 1431 if(other_reg >= 0 && jit_reg_is_used(regs->assigned, other_reg)) 1432 { 1433 continue; 1434 } 1435 1436 if((desc->value->in_global_register && desc->value->global_reg == reg) 1437 || (desc->value->in_register && desc->value->reg == reg)) 1438 { 1439 use_cost = 0; 1440 } 1441 else 1442 { 1443 use_cost = COST_COPY; 1444 } 1445 if(desc2->value->has_global_register && desc2->value->global_reg != reg) 1446 { 1447 use_cost += COST_GLOBAL_BIAS; 1448 } 1449 1450 if(index != 0 && regs->ternary && regs->descs[0].value 1451 && thrashes_value(gen, desc, reg, other_reg, ®s->descs[0])) 1452 { 1453 use_cost += COST_THRASH; 1454 } 1455 else if(index != 1 && regs->descs[1].value 1456 && thrashes_value(gen, desc, reg, other_reg, ®s->descs[1])) 1457 { 1458 use_cost += COST_THRASH; 1459 } 1460 else if(index != 2 && regs->descs[2].value 1461 && thrashes_value(gen, desc, reg, other_reg, ®s->descs[2])) 1462 { 1463 use_cost += COST_THRASH; 1464 } 1465 1466 clobber = clobbers_register(gen, regs, index, reg, other_reg); 1467 if((clobber & CLOBBER_INPUT_VALUE) != 0) 1468 { 1469 if(desc->used) 1470 { 1471 use_cost += COST_SPILL_CLEAN; 1472 } 1473 } 1474 if((clobber & (CLOBBER_REG | CLOBBER_OTHER_REG)) != 0) 1475 { 1476 if(jit_reg_is_used(gen->permanent, reg)) 1477 { 1478 continue; 1479 } 1480 if(other_reg >= 0 && jit_reg_is_used(gen->permanent, other_reg)) 1481 { 1482 #if ALLOW_CLOBBER_GLOBAL 1483 use_cost += COST_CLOBBER_GLOBAL; 1484 #else 1485 continue; 1486 #endif 1487 } 1488 if(!jit_reg_is_used(regs->clobber, reg) 1489 && !(other_reg >= 0 && jit_reg_is_used(regs->clobber, other_reg))) 1490 { 1491 use_cost += compute_spill_cost(gen, regs, reg, other_reg); 1492 } 1493 } 1494 1495 #ifdef JIT_REG_DEBUG 1496 printf("reg = %d, other_reg = %d, use_cost = %d\n", reg, other_reg, use_cost); 1497 #endif 1498 1499 if(use_cost < suitable_cost 1500 || (use_cost == suitable_cost 1501 && gen->contents[reg].num_values > 0 1502 && gen->contents[reg].age < suitable_age)) 1503 { 1504 /* This is the oldest suitable register of this type */ 1505 suitable_reg = reg; 1506 suitable_other_reg = other_reg; 1507 suitable_cost = use_cost; 1508 suitable_age = gen->contents[reg].age; 1509 } 1510 } 1511 1512 if(suitable_reg >= 0) 1513 { 1514 set_regdesc_register(gen, regs, index, suitable_reg, suitable_other_reg); 1515 } 1516 else 1517 { 1518 jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); 1519 } 1520 } 1521 1522 /* 1523 * Assign diplicate input value to the same register if possible. 1524 * The first value has to be already assigned. The second value 1525 * is assigned to the same register if it is equal to the first 1526 * and neither of them is clobbered. 1527 */ 1528 static void 1529 check_duplicate_value(_jit_regs_t *regs, _jit_regdesc_t *desc1, _jit_regdesc_t *desc2) 1530 { 1531 if(desc2->reg < 0 && desc1->reg >= 0 && are_values_equal(desc1, desc2) 1532 #ifdef JIT_REG_STACK 1533 && (!IS_STACK_REG(desc1->reg) || regs->x87_arith) 1534 #endif 1535 && !desc1->early_clobber && !desc2->early_clobber) 1536 { 1537 desc2->reg = desc1->reg; 1538 desc2->other_reg = desc1->other_reg; 1539 desc2->duplicate = 1; 1540 } 1541 } 1542 1543 #ifdef JIT_REG_STACK 1544 1545 /* 1546 * For x87 instructions choose between pop and no-pop variants. 1547 */ 1548 static void 1549 select_nopop_or_pop(jit_gencode_t gen, _jit_regs_t *regs) 1550 { 1551 int keep1, keep2; 1552 1553 if(!regs->x87_arith || !regs->descs[1].value || !regs->descs[2].value) 1554 { 1555 return; 1556 } 1557 1558 /* Equal values should be assigned to one register and this is 1559 going to work only with no-pop instructions. */ 1560 if(are_values_equal(®s->descs[1], ®s->descs[2])) 1561 { 1562 regs->no_pop = 1; 1563 return; 1564 } 1565 1566 /* Determine if we might want to keep input values in registers 1567 after the instruction completion. */ 1568 if(regs->descs[1].value->in_register) 1569 { 1570 keep1 = is_register_alive(gen, regs, regs->descs[1].value->reg); 1571 } 1572 else 1573 { 1574 keep1 = (regs->descs[1].used 1575 && (regs->descs[1].value != regs->descs[0].value) 1576 && !regs->descs[1].clobber); 1577 } 1578 if(regs->descs[2].value->in_register) 1579 { 1580 keep2 = is_register_alive(gen, regs, regs->descs[2].value->reg); 1581 } 1582 else 1583 { 1584 keep2 = (regs->descs[2].used 1585 && (regs->descs[2].value != regs->descs[0].value) 1586 && !regs->descs[2].clobber); 1587 } 1588 1589 regs->no_pop = (keep1 || keep2); 1590 } 1591 1592 static void 1593 select_stack_order(jit_gencode_t gen, _jit_regs_t *regs) 1594 { 1595 _jit_regdesc_t *desc1; 1596 _jit_regdesc_t *desc2; 1597 int top_index; 1598 1599 #ifdef JIT_REG_DEBUG 1600 printf("select_stack_order()\n"); 1601 #endif 1602 1603 if(!regs->x87_arith || regs->wanted_stack_count != 2) 1604 { 1605 return; 1606 } 1607 1608 desc1 = ®s->descs[1]; 1609 desc2 = ®s->descs[2]; 1610 1611 /* Choose instruction that results into fewer exchanges. If either 1612 of two arguments may be on the stack top choose the second to be 1613 on top. */ 1614 /* TODO: See if the next instruction wants the output or remaining 1615 input to be on the stack top. */ 1616 if(desc2->copy || desc2->load) 1617 { 1618 /* the second argument is going to be on the top */ 1619 top_index = 2; 1620 } 1621 else if(desc1->copy || desc1->load) 1622 { 1623 /* the first argument is going to be on the top */ 1624 top_index = 1; 1625 } 1626 else if(desc2->value->reg == (gen->reg_stack_top - 1)) 1627 { 1628 /* the second argument is already on the top */ 1629 top_index = 2; 1630 } 1631 else if(desc1->value->reg == (gen->reg_stack_top - 1)) 1632 { 1633 /* the first argument is already on the top */ 1634 top_index = 1; 1635 } 1636 else 1637 { 1638 top_index = 2; 1639 } 1640 1641 if(regs->no_pop) 1642 { 1643 regs->flip_args = (top_index == 2); 1644 } 1645 else if(regs->reversible) 1646 { 1647 if(top_index == 2) 1648 { 1649 regs->flip_args = 1; 1650 regs->dest_input_index = 1; 1651 } 1652 else 1653 { 1654 regs->flip_args = 0; 1655 regs->dest_input_index = 2; 1656 } 1657 } 1658 else /*if(regs->commutative)*/ 1659 { 1660 regs->flip_args = 1; 1661 regs->dest_input_index = 1; 1662 1663 if(top_index != 2) 1664 { 1665 swap_values(®s->descs[1], ®s->descs[2]); 1666 } 1667 } 1668 1669 #ifdef JIT_REG_DEBUG 1670 printf("top_index = %d, flip_args = %d, dest_input_index = %d\n", 1671 top_index, regs->flip_args, regs->dest_input_index); 1672 #endif 1673 } 1674 1675 static void 1676 adjust_assignment(jit_gencode_t gen, _jit_regs_t *regs, int index) 1677 { 1678 _jit_regdesc_t *desc, *desc2; 1679 1680 #ifdef JIT_REG_DEBUG 1681 printf("adjust_assignment(%d)\n", index); 1682 #endif 1683 1684 desc = ®s->descs[index]; 1685 if(!desc->value || !IS_STACK_REG(desc->reg)) 1686 { 1687 return; 1688 } 1689 1690 if(regs->wanted_stack_count == 0) 1691 { 1692 /* an op with stack dest and non-stack args */ 1693 #ifdef JIT_REG_DEBUG 1694 if(index != 0 || regs->ternary) 1695 { 1696 printf("*** Wrong stack register count! ***\n"); 1697 abort(); 1698 } 1699 #endif 1700 desc->reg = gen->reg_stack_top; 1701 } 1702 else if(regs->wanted_stack_count == 1) 1703 { 1704 /* either a unary op or a binary op with duplicate value */ 1705 desc->reg = gen->reg_stack_top - regs->loaded_stack_count; 1706 } 1707 else if(regs->wanted_stack_count == 2) 1708 { 1709 /* a binary op */ 1710 1711 /* find the input value the output goes to */ 1712 if(index == 0) 1713 { 1714 if(regs->x87_arith) 1715 { 1716 index = regs->dest_input_index; 1717 } 1718 else 1719 { 1720 index = 2; 1721 } 1722 desc2 = ®s->descs[index]; 1723 } 1724 else 1725 { 1726 desc2 = desc; 1727 } 1728 1729 if(regs->flip_args) 1730 { 1731 if(regs->x87_arith && index == 1 1732 && desc2->value->in_register && !desc2->copy) 1733 { 1734 desc->reg = desc2->value->reg; 1735 } 1736 else 1737 { 1738 desc->reg = (gen->reg_stack_top 1739 - regs->loaded_stack_count 1740 + index - 1); 1741 } 1742 } 1743 else 1744 { 1745 if(regs->x87_arith && index == 2 1746 && desc2->value->in_register && !desc2->copy) 1747 { 1748 desc->reg = desc2->value->reg; 1749 } 1750 else 1751 { 1752 desc->reg = (gen->reg_stack_top 1753 - regs->loaded_stack_count 1754 + regs->wanted_stack_count 1755 - index); 1756 } 1757 } 1758 } 1759 1760 #ifdef JIT_REG_DEBUG 1761 printf("reg = %d\n", desc->reg); 1762 if(desc->reg < JIT_REG_STACK_START || desc->reg > JIT_REG_STACK_END) 1763 { 1764 printf("*** Invalid stack register! ***\n"); 1765 abort(); 1766 } 1767 #endif 1768 } 1769 1770 #endif 1771 1772 /* 1773 * Associate a temporary with register. 1774 */ 1775 static void 1776 bind_temporary(jit_gencode_t gen, int reg, int other_reg) 1777 { 1778 #ifdef JIT_REG_DEBUG 1779 printf("bind_temporary(reg = %d, other_reg = %d)\n", reg, other_reg); 1780 #endif 1781 1782 gen->contents[reg].num_values = 0; 1783 gen->contents[reg].age = 0; 1784 gen->contents[reg].used_for_temp = 1; 1785 gen->contents[reg].is_long_end = 0; 1786 gen->contents[reg].is_long_start = 0; 1787 if(other_reg >= 0) 1788 { 1789 gen->contents[other_reg].num_values = 0; 1790 gen->contents[other_reg].age = 0; 1791 gen->contents[other_reg].used_for_temp = 1; 1792 gen->contents[other_reg].is_long_end = 0; 1793 gen->contents[other_reg].is_long_start = 0; 1794 } 1795 } 1796 1797 /* 1798 * Associate value with register. 1799 */ 1800 static void 1801 bind_value(jit_gencode_t gen, jit_value_t value, int reg, int other_reg, int still_in_frame) 1802 { 1803 #ifdef JIT_REG_DEBUG 1804 printf("bind_value(value = "); 1805 jit_dump_value(stdout, jit_value_get_function(value), value, 0); 1806 printf(", reg = %d, other_reg = %d, still_in_frame = %d)\n", 1807 reg, other_reg, still_in_frame); 1808 #endif 1809 1810 if(value->has_global_register && value->global_reg == reg) 1811 { 1812 value->in_register = 0; 1813 value->in_global_register = 1; 1814 return; 1815 } 1816 1817 if(value->is_constant) 1818 { 1819 still_in_frame = 0; 1820 } 1821 1822 #ifdef JIT_REG_DEBUG 1823 if(gen->contents[reg].num_values == JIT_MAX_REG_VALUES) 1824 { 1825 printf("*** Too many values for one register! ***\n"); 1826 abort(); 1827 } 1828 #endif 1829 1830 gen->contents[reg].values[gen->contents[reg].num_values] = value; 1831 ++(gen->contents[reg].num_values); 1832 gen->contents[reg].age = gen->current_age; 1833 gen->contents[reg].used_for_temp = 0; 1834 gen->contents[reg].is_long_end = 0; 1835 if(other_reg == -1) 1836 { 1837 gen->contents[reg].is_long_start = 0; 1838 } 1839 else 1840 { 1841 gen->contents[reg].is_long_start = 1; 1842 gen->contents[other_reg].num_values = 0; 1843 gen->contents[other_reg].age = gen->current_age; 1844 gen->contents[other_reg].used_for_temp = 0; 1845 gen->contents[other_reg].is_long_start = 0; 1846 gen->contents[other_reg].is_long_end = 1; 1847 } 1848 ++(gen->current_age); 1849 1850 /* Adjust the value to reflect that it is in "reg", and maybe the frame */ 1851 value->in_register = 1; 1852 if(value->has_global_register) 1853 { 1854 value->in_global_register = still_in_frame; 1855 } 1856 else 1857 { 1858 value->in_frame = still_in_frame; 1859 } 1860 value->reg = reg; 1861 } 1862 1863 /* 1864 * Disassociate value with register. 1865 */ 1866 static void 1867 unbind_value(jit_gencode_t gen, jit_value_t value, int reg, int other_reg) 1868 { 1869 int index; 1870 1871 #ifdef JIT_REG_DEBUG 1872 printf("unbind_value(value = "); 1873 jit_dump_value(stdout, jit_value_get_function(value), value, 0); 1874 printf(", reg = %d, other_reg = %d)\n", reg, other_reg); 1875 #endif 1876 1877 if(!value->in_register || value->reg != reg) 1878 { 1879 return; 1880 } 1881 1882 value->in_register = 0; 1883 value->reg = -1; 1884 1885 for(index = gen->contents[reg].num_values - 1; index >= 0; --index) 1886 { 1887 if(gen->contents[reg].values[index] == value) 1888 { 1889 --(gen->contents[reg].num_values); 1890 for(; index < gen->contents[reg].num_values; index++) 1891 { 1892 gen->contents[reg].values[index] = gen->contents[reg].values[index + 1]; 1893 } 1894 break; 1895 } 1896 } 1897 1898 if(gen->contents[reg].num_values == 0 && other_reg >= 0) 1899 { 1900 gen->contents[reg].is_long_start = 0; 1901 gen->contents[other_reg].is_long_end = 0; 1902 } 1903 } 1904 1905 /* 1906 * Swap the contents of a register and the top of the register stack. If 1907 * the register is not a stack register then the function has no effect. 1908 */ 1909 #ifdef JIT_REG_STACK 1910 static void 1911 exch_stack_top(jit_gencode_t gen, int reg, int pop) 1912 { 1913 int top, index; 1914 int num_values, used_for_temp, age; 1915 jit_value_t value1, value2; 1916 1917 #ifdef JIT_REG_DEBUG 1918 printf("exch_stack_top(reg = %d, pop = %d)\n", reg, pop); 1919 #endif 1920 1921 if(!IS_STACK_REG(reg)) 1922 { 1923 return; 1924 } 1925 1926 /* Find the top of the stack. */ 1927 top = gen->reg_stack_top - 1; 1928 1929 if(pop) 1930 { 1931 /* Generate move/pop-top instruction. */ 1932 _jit_gen_move_top(gen, reg); 1933 --(gen->reg_stack_top); 1934 } 1935 else 1936 { 1937 /* Generate exchange instruction. */ 1938 _jit_gen_exch_top(gen, reg); 1939 } 1940 1941 /* Update information about the contents of the registers. */ 1942 for(index = 0; 1943 index < gen->contents[reg].num_values || index < gen->contents[top].num_values; 1944 index++) 1945 { 1946 value1 = (index < gen->contents[top].num_values 1947 ? gen->contents[top].values[index] : 0); 1948 value2 = (index < gen->contents[reg].num_values 1949 ? gen->contents[reg].values[index] : 0); 1950 1951 if(value1) 1952 { 1953 value1->reg = reg; 1954 } 1955 gen->contents[reg].values[index] = value1; 1956 1957 if(pop) 1958 { 1959 if(value2) 1960 { 1961 value2->in_register = 0; 1962 value2->reg = -1; 1963 } 1964 gen->contents[top].values[index] = 0; 1965 } 1966 else 1967 { 1968 if(value2) 1969 { 1970 value2->reg = top; 1971 } 1972 gen->contents[top].values[index] = value2; 1973 } 1974 } 1975 1976 if(pop) 1977 { 1978 num_values = 0; 1979 used_for_temp = 0; 1980 age = 0; 1981 } 1982 else 1983 { 1984 num_values = gen->contents[reg].num_values; 1985 used_for_temp = gen->contents[reg].used_for_temp; 1986 age = gen->contents[reg].age; 1987 } 1988 gen->contents[reg].num_values = gen->contents[top].num_values; 1989 gen->contents[reg].used_for_temp = gen->contents[top].used_for_temp; 1990 gen->contents[reg].age = gen->contents[top].age; 1991 gen->contents[top].num_values = num_values; 1992 gen->contents[top].used_for_temp = used_for_temp; 1993 gen->contents[top].age = age; 1994 } 1995 #endif 1996 1997 /* 1998 * Drop value from the register and optionally bind a temporary value in place of it. 1999 */ 2000 static void 2001 free_value(jit_gencode_t gen, jit_value_t value, int reg, int other_reg, int temp) 2002 { 2003 #ifdef JIT_REG_DEBUG 2004 printf("free_value(value = "); 2005 jit_dump_value(stdout, jit_value_get_function(value), value, 0); 2006 printf(", reg = %d, other_reg = %d, temp = %d)\n", reg, other_reg, temp); 2007 #endif 2008 2009 /* Never free global registers. */ 2010 if(value->has_global_register && value->global_reg == reg) 2011 { 2012 return; 2013 } 2014 2015 if(gen->contents[reg].num_values == 1) 2016 { 2017 if(temp) 2018 { 2019 unbind_value(gen, value, reg, other_reg); 2020 bind_temporary(gen, reg, other_reg); 2021 return; 2022 } 2023 #ifdef JIT_REG_STACK 2024 if(IS_STACK_REG(reg)) 2025 { 2026 /* Free stack register. */ 2027 exch_stack_top(gen, reg, 1); 2028 return; 2029 } 2030 #endif 2031 } 2032 2033 unbind_value(gen, value, reg, other_reg); 2034 } 2035 2036 /* 2037 * Save the value from the register into its frame position and optionally free it. 2038 * If the value is already in the frame or is a constant then it is not saved but 2039 * the free option still applies to them. 2040 */ 2041 static void 2042 save_value(jit_gencode_t gen, jit_value_t value, int reg, int other_reg, int free) 2043 { 2044 #ifdef JIT_REG_DEBUG 2045 printf("save_value(value = "); 2046 jit_dump_value(stdout, jit_value_get_function(value), value, 0); 2047 printf(", reg = %d, other_reg = %d, free=%d)\n", reg, other_reg, free); 2048 #endif 2049 /* First take care of values that reside in global registers. */ 2050 if(value->has_global_register) 2051 { 2052 /* Never free global registers. */ 2053 if(value->global_reg == reg) 2054 { 2055 return; 2056 } 2057 2058 if(!value->in_global_register) 2059 { 2060 _jit_gen_spill_reg(gen, reg, other_reg, value); 2061 value->in_global_register = 1; 2062 } 2063 if(free) 2064 { 2065 unbind_value(gen, value, reg, other_reg); 2066 } 2067 return; 2068 } 2069 2070 /* Take care of constants and values that are already in frame. */ 2071 if(value->is_constant || value->in_frame) 2072 { 2073 if(free) 2074 { 2075 free_value(gen, value, reg, other_reg, 0); 2076 } 2077 return; 2078 } 2079 2080 /* Now really save the value into the frame. */ 2081 #ifdef JIT_REG_STACK 2082 if(IS_STACK_REG(reg)) 2083 { 2084 int top; 2085 2086 /* Find the top of the stack. */ 2087 top = gen->reg_stack_top - 1; 2088 2089 /* Move the value on the stack top if it is not already there. */ 2090 if(top != reg) 2091 { 2092 exch_stack_top(gen, reg, 0); 2093 } 2094 2095 if(free) 2096 { 2097 if(gen->contents[top].num_values == 1) 2098 { 2099 _jit_gen_spill_top(gen, top, value, 1); 2100 --(gen->reg_stack_top); 2101 } 2102 else 2103 { 2104 _jit_gen_spill_top(gen, top, value, 0); 2105 } 2106 unbind_value(gen, value, top, 0); 2107 } 2108 else 2109 { 2110 _jit_gen_spill_top(gen, top, value, 0); 2111 } 2112 } 2113 else 2114 #endif 2115 { 2116 _jit_gen_spill_reg(gen, reg, other_reg, value); 2117 if(free) 2118 { 2119 unbind_value(gen, value, reg, other_reg); 2120 } 2121 } 2122 2123 value->in_frame = 1; 2124 } 2125 2126 /* 2127 * Spill a specific register. 2128 */ 2129 static void 2130 spill_register(jit_gencode_t gen, int reg) 2131 { 2132 int other_reg, index; 2133 jit_value_t value; 2134 2135 #ifdef JIT_REG_DEBUG 2136 printf("spill_register(reg = %d)\n", reg); 2137 #endif 2138 2139 /* Find the other register in a long pair */ 2140 if(gen->contents[reg].is_long_start) 2141 { 2142 other_reg = jit_reg_other_reg(reg); 2143 } 2144 else if(gen->contents[reg].is_long_end) 2145 { 2146 other_reg = reg; 2147 reg = get_long_pair_start(reg); 2148 } 2149 else 2150 { 2151 other_reg = -1; 2152 } 2153 2154 for(index = gen->contents[reg].num_values - 1; index >= 0; --index) 2155 { 2156 value = gen->contents[reg].values[index]; 2157 save_value(gen, value, reg, other_reg, 1); 2158 } 2159 } 2160 2161 /* 2162 * Spill a register clobbered by the instruction. 2163 */ 2164 static void 2165 spill_clobbered_register(jit_gencode_t gen, _jit_regs_t *regs, int reg) 2166 { 2167 int other_reg, index, usage; 2168 jit_value_t value; 2169 2170 #ifdef JIT_REG_DEBUG 2171 printf("spill_clobbered_register(reg = %d)\n", reg); 2172 #endif 2173 2174 #ifdef JIT_REG_STACK 2175 /* For a stack register spill it in two passes. First drop values that 2176 reqiure neither spilling nor a generation of the free instruction. 2177 Then lazily exchange the register with the top and spill or free it 2178 as necessary. This approach might save a exch/free instructions in 2179 certain cases. */ 2180 if(IS_STACK_REG(reg)) 2181 { 2182 for(index = gen->contents[reg].num_values - 1; index >= 0; --index) 2183 { 2184 if(gen->contents[reg].num_values == 1) 2185 { 2186 break; 2187 } 2188 2189 value = gen->contents[reg].values[index]; 2190 usage = value_usage(regs, value); 2191 if((usage & VALUE_INPUT) != 0) 2192 { 2193 continue; 2194 } 2195 if((usage & VALUE_DEAD) != 0 || value->in_frame) 2196 { 2197 unbind_value(gen, value, reg, -1); 2198 } 2199 } 2200 for(index = gen->contents[reg].num_values - 1; index >= 0; --index) 2201 { 2202 int top; 2203 2204 value = gen->contents[reg].values[index]; 2205 usage = value_usage(regs, value); 2206 if((usage & VALUE_INPUT) != 0) 2207 { 2208 if((usage & VALUE_DEAD) != 0 || value->in_frame) 2209 { 2210 continue; 2211 } 2212 2213 top = gen->reg_stack_top - 1; 2214 if(reg != top) 2215 { 2216 exch_stack_top(gen, reg, 0); 2217 reg = top; 2218 } 2219 2220 save_value(gen, value, reg, -1, 0); 2221 } 2222 else 2223 { 2224 top = gen->reg_stack_top - 1; 2225 if(reg != top) 2226 { 2227 exch_stack_top(gen, reg, 0); 2228 reg = top; 2229 } 2230 2231 if((usage & VALUE_DEAD) != 0 || value->in_frame) 2232 { 2233 free_value(gen, value, reg, -1, 0); 2234 } 2235 else 2236 { 2237 save_value(gen, value, reg, -1, 1); 2238 } 2239 } 2240 } 2241 } 2242 else 2243 #endif 2244 { 2245 /* Find the other register in a long pair */ 2246 if(gen->contents[reg].is_long_start) 2247 { 2248 other_reg = jit_reg_other_reg(reg); 2249 } 2250 else if(gen->contents[reg].is_long_end) 2251 { 2252 other_reg = reg; 2253 reg = get_long_pair_start(reg); 2254 } 2255 else 2256 { 2257 other_reg = -1; 2258 } 2259 2260 for(index = gen->contents[reg].num_values - 1; index >= 0; --index) 2261 { 2262 value = gen->contents[reg].values[index]; 2263 usage = value_usage(regs, value); 2264 if((usage & VALUE_DEAD) == 0) 2265 { 2266 if((usage & VALUE_INPUT) == 0) 2267 { 2268 save_value(gen, value, reg, other_reg, 1); 2269 } 2270 else 2271 { 2272 save_value(gen, value, reg, other_reg, 0); 2273 } 2274 } 2275 else 2276 { 2277 if((usage & VALUE_INPUT) == 0) 2278 { 2279 free_value(gen, value, reg, other_reg, 0); 2280 } 2281 } 2282 } 2283 } 2284 } 2285 2286 static void 2287 update_age(jit_gencode_t gen, _jit_regdesc_t *desc) 2288 { 2289 int reg, other_reg; 2290 2291 reg = desc->value->reg; 2292 if(gen->contents[reg].is_long_start) 2293 { 2294 other_reg = jit_reg_other_reg(reg); 2295 } 2296 else 2297 { 2298 other_reg = -1; 2299 } 2300 2301 gen->contents[reg].age = gen->current_age; 2302 if(other_reg >= 0) 2303 { 2304 gen->contents[other_reg].age = gen->current_age; 2305 } 2306 ++(gen->current_age); 2307 } 2308 2309 static void 2310 save_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index) 2311 { 2312 _jit_regdesc_t *desc; 2313 int reg, other_reg; 2314 2315 #ifdef JIT_REG_DEBUG 2316 printf("save_input_value(%d)\n", index); 2317 #endif 2318 2319 desc = ®s->descs[index]; 2320 if(!desc->value || !desc->value->in_register || !desc->store) 2321 { 2322 return; 2323 } 2324 2325 reg = desc->value->reg; 2326 if(gen->contents[reg].is_long_start) 2327 { 2328 other_reg = jit_reg_other_reg(reg); 2329 } 2330 else 2331 { 2332 other_reg = -1; 2333 } 2334 2335 if(desc->thrash) 2336 { 2337 save_value(gen, desc->value, reg, other_reg, 1); 2338 } 2339 else 2340 { 2341 save_value(gen, desc->value, reg, other_reg, 0); 2342 } 2343 } 2344 2345 static void 2346 free_output_value(jit_gencode_t gen, _jit_regs_t *regs) 2347 { 2348 _jit_regdesc_t *desc; 2349 int reg, other_reg; 2350 2351 #ifdef JIT_REG_DEBUG 2352 printf("free_output_value()\n"); 2353 #endif 2354 2355 desc = ®s->descs[0]; 2356 if(!(desc->value && desc->value->in_register)) 2357 { 2358 return; 2359 } 2360 if(desc->value == regs->descs[1].value || desc->value == regs->descs[2].value) 2361 { 2362 return; 2363 } 2364 2365 reg = desc->value->reg; 2366 if(gen->contents[reg].is_long_start) 2367 { 2368 other_reg = jit_reg_other_reg(reg); 2369 } 2370 else 2371 { 2372 other_reg = -1; 2373 } 2374 2375 free_value(gen, desc->value, reg, other_reg, 0); 2376 } 2377 2378 static void 2379 load_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index) 2380 { 2381 _jit_regdesc_t *desc; 2382 2383 #ifdef JIT_REG_DEBUG 2384 printf("load_input_value(%d)\n", index); 2385 #endif 2386 2387 desc = ®s->descs[index]; 2388 if(!desc->value || desc->duplicate) 2389 { 2390 return; 2391 } 2392 2393 if(desc->value->has_global_register) 2394 { 2395 if(desc->value->in_global_register && desc->value->global_reg == desc->reg) 2396 { 2397 return; 2398 } 2399 if(desc->value->in_register && desc->value->reg == desc->reg) 2400 { 2401 update_age(gen, desc); 2402 return; 2403 } 2404 _jit_gen_load_value(gen, desc->reg, desc->other_reg, desc->value); 2405 } 2406 else if(desc->value->in_register) 2407 { 2408 if(desc->value->reg == desc->reg) 2409 { 2410 update_age(gen, desc); 2411 if(IS_STACK_REG(desc->reg)) 2412 { 2413 desc->stack_reg = desc->reg; 2414 } 2415 return; 2416 } 2417 2418 #ifdef JIT_REG_STACK 2419 if(IS_STACK_REG(desc->reg)) 2420 { 2421 _jit_gen_load_value(gen, gen->reg_stack_top, -1, desc->value); 2422 desc->stack_reg = gen->reg_stack_top++; 2423 bind_temporary(gen, desc->stack_reg, -1); 2424 } 2425 else 2426 #endif 2427 { 2428 _jit_gen_load_value(gen, desc->reg, desc->other_reg, desc->value); 2429 bind_temporary(gen, desc->reg, desc->other_reg); 2430 } 2431 } 2432 else 2433 { 2434 #ifdef JIT_REG_STACK 2435 if(IS_STACK_REG(desc->reg)) 2436 { 2437 _jit_gen_load_value(gen, gen->reg_stack_top, -1, desc->value); 2438 desc->stack_reg = gen->reg_stack_top++; 2439 bind_value(gen, desc->value, desc->stack_reg, -1, 1); 2440 } 2441 else 2442 #endif 2443 { 2444 _jit_gen_load_value(gen, desc->reg, desc->other_reg, desc->value); 2445 bind_value(gen, desc->value, desc->reg, desc->other_reg, 1); 2446 } 2447 } 2448 } 2449 2450 #ifdef JIT_REG_STACK 2451 static void 2452 move_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index) 2453 { 2454 _jit_regdesc_t *desc; 2455 int src_reg, dst_reg; 2456 2457 #ifdef JIT_REG_DEBUG 2458 printf("move_input_value(%d)\n", index); 2459 #endif 2460 2461 desc = ®s->descs[index]; 2462 if(!desc->value || desc->duplicate || !desc->value->in_register) 2463 { 2464 return; 2465 } 2466 if(!IS_STACK_REG(desc->value->reg)) 2467 { 2468 return; 2469 } 2470 2471 if(desc->copy) 2472 { 2473 src_reg = desc->stack_reg; 2474 if(src_reg < 0) 2475 { 2476 return; 2477 } 2478 } 2479 else 2480 { 2481 src_reg = desc->value->reg; 2482 } 2483 2484 if(desc->reg < gen->reg_stack_top) 2485 { 2486 dst_reg = desc->reg; 2487 } 2488 else 2489 { 2490 dst_reg = gen->reg_stack_top - 1; 2491 } 2492 2493 if(src_reg != dst_reg) 2494 { 2495 if(src_reg != (gen->reg_stack_top - 1)) 2496 { 2497 exch_stack_top(gen, src_reg, 0); 2498 } 2499 if(dst_reg != (gen->reg_stack_top - 1)) 2500 { 2501 exch_stack_top(gen, dst_reg, 0); 2502 } 2503 } 2504 } 2505 #endif 2506 2507 #ifdef JIT_REG_STACK 2508 static void 2509 pop_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index) 2510 { 2511 _jit_regdesc_t *desc; 2512 2513 #ifdef JIT_REG_DEBUG 2514 printf("pop_input_value(%d)\n", index); 2515 #endif 2516 2517 desc = ®s->descs[index]; 2518 if(!desc->value || desc->duplicate) 2519 { 2520 return; 2521 } 2522 2523 if(IS_STACK_REG(desc->reg)) 2524 { 2525 if(desc->copy) 2526 { 2527 gen->contents[desc->reg].used_for_temp = 0; 2528 } 2529 else 2530 { 2531 unbind_value(gen, desc->value, desc->reg, 0); 2532 } 2533 --(gen->reg_stack_top); 2534 } 2535 } 2536 #endif 2537 2538 static void 2539 commit_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index, int killed) 2540 { 2541 _jit_regdesc_t *desc; 2542 int reg, other_reg; 2543 2544 #ifdef JIT_REG_DEBUG 2545 printf("commit_input_value(%d)\n", index); 2546 #endif 2547 2548 desc = ®s->descs[index]; 2549 if(!desc->value || desc->duplicate) 2550 { 2551 return; 2552 } 2553 2554 #ifdef JIT_REG_STACK 2555 if(!IS_STACK_REG(desc->reg)) 2556 { 2557 killed = 0; 2558 } 2559 #endif 2560 2561 if(desc->copy) 2562 { 2563 #ifdef JIT_REG_STACK 2564 if(killed) 2565 { 2566 killed = 0; 2567 } 2568 else 2569 #endif 2570 { 2571 gen->contents[desc->reg].used_for_temp = 0; 2572 if(desc->other_reg >= 0) 2573 { 2574 gen->contents[desc->other_reg].used_for_temp = 0; 2575 } 2576 } 2577 } 2578 2579 #ifdef JIT_REG_STACK 2580 if(!killed && desc->kill && desc->value->in_register) 2581 #else 2582 if(desc->kill && desc->value->in_register) 2583 #endif 2584 { 2585 reg = desc->value->reg; 2586 if(gen->contents[reg].is_long_start) 2587 { 2588 other_reg = jit_reg_other_reg(reg); 2589 } 2590 else 2591 { 2592 other_reg = -1; 2593 } 2594 free_value(gen, desc->value, reg, other_reg, 0); 2595 } 2596 2597 #ifdef JIT_REG_DEBUG 2598 printf("value = "); 2599 jit_dump_value(stdout, jit_value_get_function(desc->value), desc->value, 0); 2600 printf("\n"); 2601 printf("value->in_register = %d\n", desc->value->in_register); 2602 printf("value->reg = %d\n", desc->value->reg); 2603 printf("value->in_global_register = %d\n", desc->value->in_global_register); 2604 printf("value->global_reg = %d\n", desc->value->global_reg); 2605 printf("value->in_frame = %d\n", desc->value->in_frame); 2606 #endif 2607 } 2608 2609 static void 2610 commit_output_value(jit_gencode_t gen, _jit_regs_t *regs, int push_stack_top) 2611 { 2612 _jit_regdesc_t *desc; 2613 2614 #ifdef JIT_REG_DEBUG 2615 printf("commit_output_value()\n"); 2616 #endif 2617 2618 desc = ®s->descs[0]; 2619 if(!desc->value) 2620 { 2621 return; 2622 } 2623 2624 #ifdef JIT_REG_STACK 2625 if(IS_STACK_REG(desc->reg) && push_stack_top) 2626 { 2627 ++(gen->reg_stack_top); 2628 } 2629 #endif 2630 bind_value(gen, desc->value, desc->reg, desc->other_reg, 0); 2631 2632 if(!desc->used) 2633 { 2634 if(desc->live) 2635 { 2636 save_value(gen, desc->value, desc->reg, desc->other_reg, 1); 2637 } 2638 else 2639 { 2640 free_value(gen, desc->value, desc->reg, desc->other_reg, 0); 2641 } 2642 } 2643 else if(desc->kill) 2644 { 2645 save_value(gen, desc->value, desc->reg, desc->other_reg, 1); 2646 } 2647 2648 #ifdef JIT_REG_DEBUG 2649 printf("value = "); 2650 jit_dump_value(stdout, jit_value_get_function(desc->value), desc->value, 0); 2651 printf("\n"); 2652 printf("value->in_register = %d\n", desc->value->in_register); 2653 printf("value->reg = %d\n", desc->value->reg); 2654 printf("value->in_global_register = %d\n", desc->value->in_global_register); 2655 printf("value->global_reg = %d\n", desc->value->global_reg); 2656 printf("value->in_frame = %d\n", desc->value->in_frame); 2657 #endif 2658 } 2659 2660 /*@ 2661 * @deftypefun void _jit_regs_lookup (char *name) 2662 * Get the pseudo register by its name. 2663 * @end deftypefun 2664 @*/ 2665 int 2666 _jit_regs_lookup(char *name) 2667 { 2668 int reg; 2669 if(name) 2670 { 2671 for(reg = 0; reg < JIT_NUM_REGS; reg++) 2672 { 2673 if(strcmp(jit_reg_name(reg), name) == 0) 2674 { 2675 return reg; 2676 } 2677 } 2678 } 2679 return -1; 2680 } 2681 2682 /*@ 2683 * @deftypefun void _jit_regs_alloc_global (jit_gencode_t gen, jit_function_t func) 2684 * Perform global register allocation on the values in @code{func}. 2685 * This is called during function compilation just after variable 2686 * liveness has been computed. 2687 * @end deftypefun 2688 @*/ 2689 void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func) 2690 { 2691 #if JIT_NUM_GLOBAL_REGS != 0 2692 jit_value_t candidates[JIT_NUM_GLOBAL_REGS]; 2693 int num_candidates = 0; 2694 int index, reg, posn, num; 2695 jit_pool_block_t block; 2696 jit_value_t value, temp; 2697 2698 /* If the function has a "try" block, then don't do global allocation 2699 as the "longjmp" for exception throws will wipe out global registers */ 2700 if(func->has_try) 2701 { 2702 return; 2703 } 2704 2705 /* If the current function involves a tail call, then we don't do 2706 global register allocation and we also prevent the code generator 2707 from using any of the callee-saved registers. This simplifies 2708 tail calls, which don't have to worry about restoring such registers */ 2709 if(func->builder->has_tail_call) 2710 { 2711 for(reg = 0; reg < JIT_NUM_REGS; ++reg) 2712 { 2713 if((jit_reg_flags(reg) & (JIT_REG_FIXED|JIT_REG_CALL_USED)) == 0) 2714 { 2715 jit_reg_set_used(gen->permanent, reg); 2716 } 2717 } 2718 return; 2719 } 2720 2721 /* Scan all values within the function, looking for the most used. 2722 We will replace this with a better allocation strategy later */ 2723 block = func->builder->value_pool.blocks; 2724 num = (int)(func->builder->value_pool.elems_per_block); 2725 while(block != 0) 2726 { 2727 if(!(block->next)) 2728 { 2729 num = (int)(func->builder->value_pool.elems_in_last); 2730 } 2731 for(posn = 0; posn < num; ++posn) 2732 { 2733 value = (jit_value_t)(block->data + posn * sizeof(struct _jit_value)); 2734 if(value->global_candidate && value->usage_count >= JIT_MIN_USED && 2735 !(value->is_addressable) && !(value->is_volatile)) 2736 { 2737 /* Insert this candidate into the list, ordered on count */ 2738 index = 0; 2739 while(index < num_candidates && 2740 value->usage_count <= candidates[index]->usage_count) 2741 { 2742 ++index; 2743 } 2744 while(index < num_candidates) 2745 { 2746 temp = candidates[index]; 2747 candidates[index] = value; 2748 value = temp; 2749 ++index; 2750 } 2751 if(index < JIT_NUM_GLOBAL_REGS) 2752 { 2753 candidates[num_candidates++] = value; 2754 } 2755 } 2756 } 2757 block = block->next; 2758 } 2759 2760 /* Allocate registers to the candidates. We allocate from the top-most 2761 register in the allocation order, because some architectures like 2762 PPC require global registers to be saved top-down for efficiency */ 2763 reg = JIT_NUM_REGS - 1; 2764 for(index = 0; index < num_candidates; ++index) 2765 { 2766 while(reg >= 0 && (jit_reg_flags(reg) & JIT_REG_GLOBAL) == 0) 2767 { 2768 --reg; 2769 } 2770 candidates[index]->has_global_register = 1; 2771 candidates[index]->in_global_register = 1; 2772 candidates[index]->global_reg = (short)reg; 2773 jit_reg_set_used(gen->touched, reg); 2774 jit_reg_set_used(gen->permanent, reg); 2775 --reg; 2776 } 2777 2778 #endif 2779 } 2780 2781 /*@ 2782 * @deftypefun void _jit_regs_init_for_block (jit_gencode_t gen) 2783 * Initialize the register allocation state for a new block. 2784 * @end deftypefun 2785 @*/ 2786 void 2787 _jit_regs_init_for_block(jit_gencode_t gen) 2788 { 2789 int reg; 2790 gen->current_age = 1; 2791 for(reg = 0; reg < JIT_NUM_REGS; ++reg) 2792 { 2793 /* Clear everything except permanent and fixed registers */ 2794 if(!jit_reg_is_used(gen->permanent, reg) 2795 && (jit_reg_flags(reg) & JIT_REG_FIXED) == 0) 2796 { 2797 gen->contents[reg].num_values = 0; 2798 gen->contents[reg].is_long_start = 0; 2799 gen->contents[reg].is_long_end = 0; 2800 gen->contents[reg].age = 0; 2801 gen->contents[reg].used_for_temp = 0; 2802 } 2803 #ifdef JIT_REG_STACK 2804 gen->reg_stack_top = JIT_REG_STACK_START; 2805 #endif 2806 } 2807 gen->inhibit = jit_regused_init; 2808 } 2809 2810 /*@ 2811 * @deftypefun void _jit_regs_spill_all (jit_gencode_t gen) 2812 * Spill all of the temporary registers to memory locations. 2813 * Normally used at the end of a block, but may also be used in 2814 * situations where a value must be in a certain register and 2815 * it is too hard to swap things around to put it there. 2816 * @end deftypefun 2817 @*/ 2818 void 2819 _jit_regs_spill_all(jit_gencode_t gen) 2820 { 2821 int reg; 2822 2823 #ifdef JIT_REG_DEBUG 2824 printf("enter _jit_regs_spill_all\n"); 2825 #endif 2826 2827 for(reg = 0; reg < JIT_NUM_REGS; reg++) 2828 { 2829 /* Skip this register if it is permanent or fixed */ 2830 if(jit_reg_is_used(gen->permanent, reg) 2831 || (jit_reg_flags(reg) & JIT_REG_FIXED) != 0) 2832 { 2833 continue; 2834 } 2835 2836 /* If this is a stack register, then we need to find the 2837 register that contains the top-most stack position, 2838 because we must spill stack registers from top down. 2839 As we spill each one, something else will become the top */ 2840 #ifdef JIT_REG_STACK 2841 if(IS_STACK_REG(reg)) 2842 { 2843 if(gen->reg_stack_top > JIT_REG_STACK_START) 2844 { 2845 spill_register(gen, gen->reg_stack_top - 1); 2846 } 2847 } 2848 else 2849 #endif 2850 { 2851 spill_register(gen, reg); 2852 } 2853 } 2854 2855 #ifdef JIT_REG_DEBUG 2856 printf("leave _jit_regs_spill_all\n\n"); 2857 #endif 2858 } 2859 2860 /*@ 2861 * @deftypefun void _jit_regs_set_incoming (jit_gencode_t gen, int reg, jit_value_t value) 2862 * Set pseudo register @code{reg} to record that it currently holds the 2863 * contents of @code{value}. The register must not contain any other 2864 * live value at this point. 2865 * @end deftypefun 2866 @*/ 2867 void 2868 _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value) 2869 { 2870 int other_reg; 2871 2872 /* Find the other register in a register pair */ 2873 other_reg = jit_reg_get_pair(value->type, reg); 2874 2875 /* avd: It's too late to spill here, if there was any 2876 value it is already cloberred by the incoming value. 2877 So for correct code generation the register must be 2878 free by now (spilled at some earlier point). */ 2879 #if 0 2880 /* Eject any values that are currently in the register */ 2881 spill_register(gen, reg); 2882 if(other_reg >= 0) 2883 { 2884 spill_register(gen, other_reg); 2885 } 2886 #endif 2887 2888 /* Record that the value is in "reg", but not in the frame */ 2889 #ifdef JIT_REG_STACK 2890 if(IS_STACK_REG(reg)) 2891 { 2892 ++(gen->reg_stack_top); 2893 } 2894 #endif 2895 bind_value(gen, value, reg, other_reg, 0); 2896 } 2897 2898 /*@ 2899 * @deftypefun void _jit_regs_set_outgoing (jit_gencode_t gen, int reg, jit_value_t value) 2900 * Load the contents of @code{value} into pseudo register @code{reg}, 2901 * spilling out the current contents. This is used to set up outgoing 2902 * parameters for a function call. 2903 * @end deftypefun 2904 @*/ 2905 void 2906 _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value) 2907 { 2908 int other_reg; 2909 2910 #ifdef JIT_BACKEND_X86 2911 jit_type_t type; 2912 2913 other_reg = -1; 2914 2915 type = jit_type_normalize(value->type); 2916 if(type) 2917 { 2918 /* We might need to put float values in register pairs under x86 */ 2919 if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG || 2920 type->kind == JIT_TYPE_FLOAT64 || type->kind == JIT_TYPE_NFLOAT) 2921 { 2922 /* Long values in outgoing registers must be in ECX:EDX, 2923 not in the ordinary register pairing of ECX:EBX */ 2924 other_reg = 2; 2925 2926 /* Force the value out of whatever register it is already in */ 2927 _jit_regs_force_out(gen, value, 0); 2928 } 2929 } 2930 #else 2931 other_reg = jit_reg_get_pair(value->type, reg); 2932 #endif 2933 2934 if(value->in_register && value->reg == reg) 2935 { 2936 /* The value is already in the register, but we may need to spill 2937 if the frame copy is not up to date with the register */ 2938 if(!(value->in_global_register || value->in_frame)) 2939 { 2940 save_value(gen, value, reg, other_reg, 0); 2941 } 2942 2943 /* The value is no longer "really" in the register. A copy is 2944 left behind, but the value itself reverts to the frame copy 2945 as we are about to kill the registers in a function call */ 2946 free_value(gen, value, reg, other_reg, 1); 2947 } 2948 else 2949 { 2950 /* Reload the value into the specified register */ 2951 spill_register(gen, reg); 2952 if(other_reg >= 0) 2953 { 2954 spill_register(gen, other_reg); 2955 } 2956 2957 _jit_gen_load_value(gen, reg, other_reg, value); 2958 } 2959 2960 jit_reg_set_used(gen->inhibit, reg); 2961 if(other_reg >= 0) 2962 { 2963 jit_reg_set_used(gen->inhibit, other_reg); 2964 } 2965 } 2966 2967 /*@ 2968 * @deftypefun void _jit_regs_clear_all_outgoing (jit_gencode_t gen) 2969 * Free registers used for outgoing parameters. This is used to 2970 * clean up after a function call. 2971 * @end deftypefun 2972 @*/ 2973 void 2974 _jit_regs_clear_all_outgoing(jit_gencode_t gen) 2975 { 2976 gen->inhibit = jit_regused_init; 2977 } 2978 2979 /* TODO: remove this function */ 2980 /*@ 2981 * @deftypefun void _jit_regs_force_out (jit_gencode_t gen, jit_value_t value, int is_dest) 2982 * If @code{value} is currently in a register, then force its value out 2983 * into the stack frame. The @code{is_dest} flag indicates that the value 2984 * will be a destination, so we don't care about the original value. 2985 * 2986 * This function is deprecated and going to be removed soon. 2987 * 2988 * @end deftypefun 2989 @*/ 2990 void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest) 2991 { 2992 int reg, other_reg; 2993 if(value->in_register) 2994 { 2995 reg = value->reg; 2996 other_reg = jit_reg_get_pair(value->type, reg); 2997 2998 if(is_dest) 2999 { 3000 free_value(gen, value, reg, other_reg, 0); 3001 } 3002 else 3003 { 3004 save_value(gen, value, reg, other_reg, 1); 3005 } 3006 } 3007 } 3008 3009 /* TODO: remove this function */ 3010 /*@ 3011 * @deftypefun int _jit_regs_load_value (jit_gencode_t gen, jit_value_t value, int destroy, int used_again) 3012 * Load a value into any register that is suitable and return that register. 3013 * If the value needs a long pair, then this will return the first register 3014 * in the pair. Returns -1 if the value will not fit into any register. 3015 * 3016 * If @code{destroy} is non-zero, then we are about to destroy the register, 3017 * so the system must make sure that such destruction will not side-effect 3018 * @code{value} or any of the other values currently in that register. 3019 * 3020 * If @code{used_again} is non-zero, then it indicates that the value is 3021 * used again further down the block. 3022 * 3023 * This function is deprecated and going to be removed soon. 3024 * 3025 * @end deftypefun 3026 @*/ 3027 int 3028 _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used_again) 3029 { 3030 int type; 3031 int reg, other_reg; 3032 int spill_cost; 3033 int suitable_reg, suitable_other_reg; 3034 int suitable_cost; 3035 int suitable_age; 3036 3037 /* If the value is in a global register, and we are not going 3038 to destroy the value, then use the global register itself. 3039 This will avoid a redundant register copy operation */ 3040 if(value->in_global_register && !destroy) 3041 { 3042 return value->global_reg; 3043 } 3044 3045 /* If the value is already in a register, then try to use that register */ 3046 if(value->in_register && (!destroy || !used_again)) 3047 { 3048 reg = value->reg; 3049 if(!used_again) 3050 { 3051 other_reg = jit_reg_get_pair(value->type, reg); 3052 free_value(gen, value, reg, other_reg, 1); 3053 } 3054 return reg; 3055 } 3056 3057 switch(jit_type_remove_tags(value->type)->kind) 3058 { 3059 case JIT_TYPE_SBYTE: 3060 case JIT_TYPE_UBYTE: 3061 case JIT_TYPE_SHORT: 3062 case JIT_TYPE_USHORT: 3063 case JIT_TYPE_INT: 3064 case JIT_TYPE_UINT: 3065 case JIT_TYPE_NINT: 3066 case JIT_TYPE_NUINT: 3067 case JIT_TYPE_SIGNATURE: 3068 case JIT_TYPE_PTR: 3069 type = JIT_REG_WORD; 3070 break; 3071 case JIT_TYPE_LONG: 3072 case JIT_TYPE_ULONG: 3073 type = JIT_REG_LONG; 3074 break; 3075 case JIT_TYPE_FLOAT32: 3076 type = JIT_REG_FLOAT32; 3077 break; 3078 case JIT_TYPE_FLOAT64: 3079 type = JIT_REG_FLOAT64; 3080 break; 3081 case JIT_TYPE_NFLOAT: 3082 type = JIT_REG_NFLOAT; 3083 break; 3084 default: 3085 return 0; 3086 } 3087 3088 suitable_reg = -1; 3089 suitable_other_reg = -1; 3090 suitable_cost = COST_TOO_MUCH; 3091 suitable_age = -1; 3092 for(reg = 0; reg < JIT_NUM_REGS; reg++) 3093 { 3094 if((jit_reg_flags(reg) & type) == 0) 3095 { 3096 continue; 3097 } 3098 if(jit_reg_is_used(gen->inhibit, reg)) 3099 { 3100 continue; 3101 } 3102 if(jit_reg_is_used(gen->permanent, reg)) 3103 { 3104 continue; 3105 } 3106 3107 other_reg = jit_reg_get_pair(value->type, reg); 3108 if(other_reg >= 0) 3109 { 3110 if(jit_reg_is_used(gen->inhibit, other_reg)) 3111 { 3112 continue; 3113 } 3114 if(jit_reg_is_used(gen->permanent, other_reg)) 3115 { 3116 continue; 3117 } 3118 } 3119 3120 spill_cost = compute_spill_cost(gen, 0, reg, other_reg); 3121 3122 if(spill_cost < suitable_cost 3123 || (spill_cost == suitable_cost 3124 && spill_cost > 0 && gen->contents[reg].age < suitable_age)) 3125 { 3126 suitable_reg = reg; 3127 suitable_other_reg = other_reg; 3128 suitable_cost = spill_cost; 3129 suitable_age = gen->contents[reg].age; 3130 } 3131 } 3132 3133 if(suitable_reg >= 0) 3134 { 3135 spill_register(gen, suitable_reg); 3136 if(suitable_other_reg >= 0) 3137 { 3138 spill_register(gen, suitable_other_reg); 3139 } 3140 3141 _jit_gen_load_value(gen, suitable_reg, suitable_other_reg, value); 3142 3143 if(!destroy && !used_again) 3144 { 3145 bind_value(gen, value, suitable_reg, suitable_other_reg, 1); 3146 } 3147 else 3148 { 3149 bind_temporary(gen, suitable_reg, suitable_other_reg); 3150 } 3151 } 3152 3153 return suitable_reg; 3154 } 3155 3156 void 3157 _jit_regs_init(jit_gencode_t gen, _jit_regs_t *regs, int flags) 3158 { 3159 int index; 3160 3161 jit_memset(regs, 0, sizeof(_jit_regs_t)); 3162 3163 regs->ternary = (flags & _JIT_REGS_TERNARY) != 0; 3164 regs->branch = (flags & _JIT_REGS_BRANCH) != 0; 3165 regs->copy = (flags & _JIT_REGS_COPY) != 0; 3166 regs->commutative = (flags & _JIT_REGS_COMMUTATIVE) != 0; 3167 regs->free_dest = (flags & _JIT_REGS_FREE_DEST) != 0; 3168 #ifdef JIT_REG_STACK 3169 regs->on_stack = (flags & _JIT_REGS_STACK) != 0; 3170 regs->x87_arith = (flags & _JIT_REGS_X87_ARITH) != 0; 3171 regs->reversible = (flags & _JIT_REGS_REVERSIBLE) != 0; 3172 regs->no_pop = (regs->on_stack & regs->copy) != 0; 3173 #endif 3174 3175 for(index = 0; index < _JIT_REGS_VALUE_MAX; index++) 3176 { 3177 regs->descs[index].reg = -1; 3178 regs->descs[index].other_reg = -1; 3179 regs->descs[index].stack_reg = -1; 3180 } 3181 for(index = 0; index < _JIT_REGS_SCRATCH_MAX; index++) 3182 { 3183 regs->scratch[index].reg = -1; 3184 } 3185 3186 regs->clobber = jit_regused_init; 3187 regs->assigned = gen->inhibit; 3188 } 3189 3190 void 3191 _jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, int flags, _jit_regclass_t *regclass) 3192 { 3193 if((insn->flags & JIT_INSN_DEST_OTHER_FLAGS) == 0) 3194 { 3195 set_regdesc_value(regs, 0, insn->dest, flags, regclass, 3196 (insn->flags & JIT_INSN_DEST_LIVE) != 0, 3197 (insn->flags & JIT_INSN_DEST_NEXT_USE) != 0); 3198 } 3199 } 3200 3201 void 3202 _jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, int flags, _jit_regclass_t *regclass) 3203 { 3204 if((insn->flags & JIT_INSN_VALUE1_OTHER_FLAGS) == 0) 3205 { 3206 set_regdesc_value(regs, 1, insn->value1, flags, regclass, 3207 (insn->flags & JIT_INSN_VALUE1_LIVE) != 0, 3208 (insn->flags & JIT_INSN_VALUE1_NEXT_USE) != 0); 3209 } 3210 } 3211 3212 void 3213 _jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, int flags, _jit_regclass_t *regclass) 3214 { 3215 if((insn->flags & JIT_INSN_VALUE2_OTHER_FLAGS) == 0) 3216 { 3217 set_regdesc_value(regs, 2, insn->value2, flags, regclass, 3218 (insn->flags & JIT_INSN_VALUE2_LIVE) != 0, 3219 (insn->flags & JIT_INSN_VALUE2_NEXT_USE) != 0); 3220 } 3221 } 3222 3223 void 3224 _jit_regs_add_scratch(_jit_regs_t *regs, _jit_regclass_t *regclass) 3225 { 3226 if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX) 3227 { 3228 regs->scratch[regs->num_scratch].reg = -1; 3229 regs->scratch[regs->num_scratch].regclass = regclass; 3230 ++regs->num_scratch; 3231 } 3232 } 3233 3234 void 3235 _jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg) 3236 { 3237 if(reg >= 0 && !IS_STACK_REG(reg)) 3238 { 3239 set_regdesc_register(gen, regs, 0, reg, other_reg); 3240 } 3241 } 3242 3243 void 3244 _jit_regs_set_value1(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg) 3245 { 3246 if(reg >= 0 && !IS_STACK_REG(reg)) 3247 { 3248 set_regdesc_register(gen, regs, 1, reg, other_reg); 3249 } 3250 } 3251 3252 void 3253 _jit_regs_set_value2(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg) 3254 { 3255 if(reg >= 0 && !IS_STACK_REG(reg)) 3256 { 3257 set_regdesc_register(gen, regs, 2, reg, other_reg); 3258 } 3259 } 3260 3261 void 3262 _jit_regs_set_scratch(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg) 3263 { 3264 if(index < regs->num_scratch && index >= 0 && reg >= 0 && !IS_STACK_REG(reg)) 3265 { 3266 set_scratch_register(gen, regs, index, reg); 3267 } 3268 } 3269 3270 int 3271 _jit_regs_get_dest(_jit_regs_t *regs) 3272 { 3273 return regs->descs[0].reg; 3274 } 3275 3276 int 3277 _jit_regs_get_value1(_jit_regs_t *regs) 3278 { 3279 return regs->descs[1].reg; 3280 } 3281 3282 int 3283 _jit_regs_get_value2(_jit_regs_t *regs) 3284 { 3285 return regs->descs[2].reg; 3286 } 3287 3288 int 3289 _jit_regs_get_dest_other(_jit_regs_t *regs) 3290 { 3291 return regs->descs[0].other_reg; 3292 } 3293 3294 int 3295 _jit_regs_get_value1_other(_jit_regs_t *regs) 3296 { 3297 return regs->descs[1].other_reg; 3298 } 3299 3300 int 3301 _jit_regs_get_value2_other(_jit_regs_t *regs) 3302 { 3303 return regs->descs[2].other_reg; 3304 } 3305 3306 int 3307 _jit_regs_get_scratch(_jit_regs_t *regs, int index) 3308 { 3309 if(index < regs->num_scratch && index >= 0) 3310 { 3311 return regs->scratch[index].reg; 3312 } 3313 return -1; 3314 } 3315 3316 void 3317 _jit_regs_clobber(_jit_regs_t *regs, int reg) 3318 { 3319 if(reg >= 0) 3320 { 3321 jit_reg_set_used(regs->clobber, reg); 3322 } 3323 } 3324 3325 void 3326 _jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs, _jit_regclass_t *regclass) 3327 { 3328 int index; 3329 3330 for(index = 0; index < regclass->num_regs; index++) 3331 { 3332 if(jit_reg_is_used(gen->permanent, index)) 3333 { 3334 continue; 3335 } 3336 jit_reg_set_used(regs->clobber, regclass->regs[index]); 3337 } 3338 } 3339 3340 void 3341 _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs) 3342 { 3343 int index; 3344 3345 for(index = 0; index < JIT_NUM_REGS; index++) 3346 { 3347 if((jit_reg_flags(index) & JIT_REG_FIXED) != 0) 3348 { 3349 continue; 3350 } 3351 if(jit_reg_is_used(gen->permanent, index)) 3352 { 3353 continue; 3354 } 3355 jit_reg_set_used(regs->clobber, index); 3356 } 3357 } 3358 3359 void 3360 _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs) 3361 { 3362 int index; 3363 3364 #ifdef JIT_REG_DEBUG 3365 printf("_jit_regs_assign()\n"); 3366 #endif 3367 3368 /* Check explicitely assigned registers */ 3369 if(regs->descs[2].value && regs->descs[2].reg >= 0) 3370 { 3371 check_duplicate_value(regs, ®s->descs[2], ®s->descs[1]); 3372 if(regs->ternary) 3373 { 3374 check_duplicate_value(regs, ®s->descs[2], ®s->descs[0]); 3375 } 3376 } 3377 if(regs->descs[1].value && regs->descs[1].reg >= 0) 3378 { 3379 if(regs->ternary) 3380 { 3381 check_duplicate_value(regs, ®s->descs[1], ®s->descs[0]); 3382 } 3383 else if(!regs->free_dest && regs->descs[0].value && regs->descs[0].reg < 0) 3384 { 3385 /* For binary or unary ops with explicitely assigned registers 3386 the output always goes to the same register as the first input 3387 value unless this is a three-address instruction. */ 3388 set_regdesc_register(gen, regs, 0, 3389 regs->descs[1].reg, 3390 regs->descs[1].other_reg); 3391 } 3392 } 3393 3394 #if JIT_REG_STACK 3395 /* Choose between x87 pop and no-pop instructions. */ 3396 select_nopop_or_pop(gen, regs); 3397 #endif 3398 3399 /* Assign output and input registers. */ 3400 if(regs->descs[0].value) 3401 { 3402 if(regs->descs[0].reg < 0) 3403 { 3404 if(regs->ternary) 3405 { 3406 choose_input_register(gen, regs, 0); 3407 } 3408 else 3409 { 3410 choose_output_register(gen, regs); 3411 } 3412 } 3413 if(regs->ternary) 3414 { 3415 check_duplicate_value(regs, ®s->descs[0], ®s->descs[1]); 3416 check_duplicate_value(regs, ®s->descs[0], ®s->descs[2]); 3417 } 3418 else if(!regs->free_dest) 3419 { 3420 choose_input_order(gen, regs); 3421 if(regs->dest_input_index) 3422 { 3423 set_regdesc_register(gen, regs, regs->dest_input_index, 3424 regs->descs[0].reg, 3425 regs->descs[0].other_reg); 3426 } 3427 } 3428 } 3429 if(regs->descs[1].value && regs->descs[1].reg < 0) 3430 { 3431 choose_input_register(gen, regs, 1); 3432 } 3433 check_duplicate_value(regs, ®s->descs[1], ®s->descs[2]); 3434 if(regs->descs[2].value && regs->descs[2].reg < 0) 3435 { 3436 choose_input_register(gen, regs, 2); 3437 } 3438 3439 /* Assign scratch registers. */ 3440 for(index = 0; index < regs->num_scratch; index++) 3441 { 3442 if(regs->scratch[index].reg < 0) 3443 { 3444 choose_scratch_register(gen, regs, index); 3445 } 3446 } 3447 3448 /* Collect information about registers. */ 3449 set_regdesc_flags(gen, regs, 0); 3450 set_regdesc_flags(gen, regs, 1); 3451 set_regdesc_flags(gen, regs, 2); 3452 } 3453 3454 void 3455 _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs) 3456 { 3457 int reg; 3458 3459 #ifdef JIT_REG_DEBUG 3460 dump_regs(gen, "enter _jit_regs_gen"); 3461 #endif 3462 3463 /* Spill clobbered registers. */ 3464 for(reg = 0; reg < JIT_NUM_REGS; reg++) 3465 { 3466 if((jit_reg_flags(reg) & JIT_REG_FIXED)) 3467 { 3468 continue; 3469 } 3470 3471 if(!jit_reg_is_used(regs->clobber, reg)) 3472 { 3473 continue; 3474 } 3475 if(jit_reg_is_used(gen->permanent, reg)) 3476 { 3477 #ifdef IS_REGISTER_OCCUPIED 3478 /* If the op computes the value assigned to the global 3479 register then it is not really clobbered. */ 3480 if(!regs->ternary 3481 && regs->descs[0].value 3482 && regs->descs[0].value->has_global_register 3483 && regs->descs[0].value->global_reg == reg) 3484 { 3485 continue; 3486 } 3487 #endif 3488 /* Oops, the global register is going to be clobbered. Save 3489 it on the stack in order to restore after the op. */ 3490 #ifdef JIT_REG_DEBUG 3491 printf("*** Spill global register: %d ***\n", reg); 3492 #endif 3493 if(regs->branch) 3494 { 3495 /* After the branch is taken there is no way 3496 to load the global register back. */ 3497 jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); 3498 } 3499 _jit_gen_spill_global(gen, reg, 0); 3500 continue; 3501 } 3502 3503 #ifdef JIT_REG_STACK 3504 /* If this is a stack register, then we need to find the 3505 register that contains the top-most stack position, 3506 because we must spill stack registers from top down. 3507 As we spill each one, something else will become the top */ 3508 if(IS_STACK_REG(reg)) 3509 { 3510 int top = gen->reg_stack_top - 1; 3511 /* spill top registers if there are any that needs to be */ 3512 for(; top >= reg && jit_reg_is_used(regs->clobber, top); top--) 3513 { 3514 spill_clobbered_register(gen, regs, top); 3515 /* If an input value is on the top then it stays there 3516 and the top position does not change. */ 3517 if(gen->contents[top].num_values > 0) 3518 { 3519 break; 3520 } 3521 } 3522 if(top > reg) 3523 { 3524 spill_clobbered_register(gen, regs, reg); 3525 } 3526 } 3527 else 3528 #endif 3529 { 3530 spill_clobbered_register(gen, regs, reg); 3531 } 3532 } 3533 3534 /* Save input values if necessary and free the output value if it is in a register */ 3535 if(regs->ternary) 3536 { 3537 save_input_value(gen, regs, 0); 3538 } 3539 else 3540 { 3541 free_output_value(gen, regs); 3542 } 3543 save_input_value(gen, regs, 1); 3544 save_input_value(gen, regs, 2); 3545 3546 #ifdef JIT_REG_STACK 3547 if(regs->wanted_stack_count > 0) 3548 { 3549 /* Adjust assignment of stack registers. */ 3550 select_stack_order(gen, regs); 3551 adjust_assignment(gen, regs, 2); 3552 adjust_assignment(gen, regs, 1); 3553 adjust_assignment(gen, regs, 0); 3554 3555 if(regs->ternary) 3556 { 3557 /* Ternary ops with only one stack register are supported. */ 3558 if(regs->loaded_stack_count > 0) 3559 { 3560 move_input_value(gen, regs, 0); 3561 move_input_value(gen, regs, 1); 3562 move_input_value(gen, regs, 2); 3563 } 3564 load_input_value(gen, regs, 0); 3565 load_input_value(gen, regs, 1); 3566 load_input_value(gen, regs, 2); 3567 } 3568 else if(regs->flip_args) 3569 { 3570 /* Shuffle the values that are already on the register stack. */ 3571 if(regs->loaded_stack_count > 0) 3572 { 3573 move_input_value(gen, regs, 1); 3574 move_input_value(gen, regs, 2); 3575 } 3576 3577 /* Load and shuffle the remaining values. */ 3578 load_input_value(gen, regs, 1); 3579 move_input_value(gen, regs, 1); 3580 load_input_value(gen, regs, 2); 3581 } 3582 else 3583 { 3584 /* Shuffle the values that are already on the register stack. */ 3585 if(regs->loaded_stack_count > 0) 3586 { 3587 move_input_value(gen, regs, 2); 3588 move_input_value(gen, regs, 1); 3589 } 3590 3591 /* Load and shuffle the remaining values. */ 3592 load_input_value(gen, regs, 2); 3593 move_input_value(gen, regs, 2); 3594 load_input_value(gen, regs, 1); 3595 } 3596 } 3597 else 3598 #endif 3599 { 3600 /* Load flat registers. */ 3601 if(regs->ternary) 3602 { 3603 load_input_value(gen, regs, 0); 3604 } 3605 #ifdef JIT_REG_STACK 3606 else if(regs->descs[0].reg >= 0 && IS_STACK_REG(regs->descs[0].reg)) 3607 { 3608 adjust_assignment(gen, regs, 0); 3609 } 3610 #endif 3611 load_input_value(gen, regs, 1); 3612 load_input_value(gen, regs, 2); 3613 } 3614 3615 #ifdef JIT_REG_DEBUG 3616 dump_regs(gen, "leave _jit_regs_gen"); 3617 #endif 3618 } 3619 3620 #ifdef JIT_REG_STACK 3621 int 3622 _jit_regs_select(_jit_regs_t *regs) 3623 { 3624 int flags; 3625 3626 flags = 0; 3627 if(regs->no_pop) 3628 { 3629 flags |= _JIT_REGS_NO_POP; 3630 } 3631 if(regs->flip_args) 3632 { 3633 flags |= _JIT_REGS_FLIP_ARGS; 3634 } 3635 if(regs->dest_input_index == 2) 3636 { 3637 flags |= _JIT_REGS_REVERSE; 3638 } 3639 return flags; 3640 } 3641 #endif 3642 3643 void 3644 _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs) 3645 { 3646 int reg; 3647 3648 #ifdef JIT_REG_DEBUG 3649 dump_regs(gen, "enter _jit_regs_commit"); 3650 #endif 3651 3652 if(regs->ternary) 3653 { 3654 #ifdef JIT_REG_STACK 3655 if(regs->wanted_stack_count > 0) 3656 { 3657 pop_input_value(gen, regs, 0); 3658 pop_input_value(gen, regs, 1); 3659 pop_input_value(gen, regs, 2); 3660 } 3661 #endif 3662 commit_input_value(gen, regs, 0, 1); 3663 commit_input_value(gen, regs, 1, 1); 3664 commit_input_value(gen, regs, 2, 1); 3665 } 3666 else if(!regs->descs[0].value) 3667 { 3668 #ifdef JIT_REG_STACK 3669 if(regs->wanted_stack_count > 0) 3670 { 3671 pop_input_value(gen, regs, 1); 3672 pop_input_value(gen, regs, 2); 3673 } 3674 #endif 3675 commit_input_value(gen, regs, 1, 1); 3676 commit_input_value(gen, regs, 2, 1); 3677 } 3678 #ifdef JIT_REG_STACK 3679 else if(regs->wanted_stack_count > 0) 3680 { 3681 int pop1, pop2; 3682 struct _jit_value temp; 3683 int reg1, reg2; 3684 3685 pop1 = pop2 = 0; 3686 if(!regs->no_pop) 3687 { 3688 if(regs->x87_arith) 3689 { 3690 if(regs->flip_args) 3691 { 3692 pop_input_value(gen, regs, 2); 3693 pop2 = 1; 3694 } 3695 else 3696 { 3697 pop_input_value(gen, regs, 1); 3698 pop1 = 1; 3699 } 3700 } 3701 else 3702 { 3703 pop_input_value(gen, regs, 1); 3704 pop_input_value(gen, regs, 2); 3705 pop1 = pop2 = 1; 3706 } 3707 } 3708 3709 if(IS_STACK_REG(regs->descs[0].reg)) 3710 { 3711 temp = *regs->descs[0].value; 3712 if(!regs->x87_arith && !regs->copy) 3713 { 3714 ++(gen->reg_stack_top); 3715 } 3716 bind_value(gen, &temp, regs->descs[0].reg, -1, 0); 3717 } 3718 3719 reg1 = ((regs->descs[1].value && regs->descs[1].value->in_register) 3720 ? regs->descs[1].value->reg : -1); 3721 reg2 = ((regs->descs[2].value && regs->descs[2].value->in_register) 3722 ? regs->descs[2].value->reg : -1); 3723 if(reg1 > reg2) 3724 { 3725 commit_input_value(gen, regs, 1, pop1); 3726 commit_input_value(gen, regs, 2, pop2); 3727 } 3728 else 3729 { 3730 commit_input_value(gen, regs, 2, pop2); 3731 commit_input_value(gen, regs, 1, pop1); 3732 } 3733 3734 if(IS_STACK_REG(regs->descs[0].reg)) 3735 { 3736 reg1 = temp.reg; 3737 free_value(gen, &temp, reg1, -1, 1); 3738 regs->descs[0].reg = reg1; 3739 regs->descs[0].other_reg = -1; 3740 } 3741 commit_output_value(gen, regs, 0); 3742 } 3743 #endif 3744 else 3745 { 3746 commit_input_value(gen, regs, 2, 0); 3747 commit_input_value(gen, regs, 1, 0); 3748 commit_output_value(gen, regs, 1); 3749 } 3750 3751 /* Load clobbered global registers. */ 3752 for(reg = JIT_NUM_REGS - 1; reg >= 0; reg--) 3753 { 3754 if(jit_reg_is_used(regs->clobber, reg) && jit_reg_is_used(gen->permanent, reg)) 3755 { 3756 #ifdef IS_REGISTER_OCCUPIED 3757 if(!regs->ternary 3758 && regs->descs[0].value 3759 && regs->descs[0].value->has_global_register 3760 && regs->descs[0].value->global_reg == reg) 3761 { 3762 continue; 3763 } 3764 #endif 3765 _jit_gen_load_global(gen, reg, 0); 3766 } 3767 } 3768 3769 #ifdef JIT_REG_DEBUG 3770 dump_regs(gen, "leave _jit_regs_commit"); 3771 #endif 3772 } 3773 3774 void 3775 _jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space) 3776 { 3777 _jit_regs_assign(gen, regs); 3778 _jit_regs_gen(gen, regs); 3779 _jit_gen_check_space(gen, space); 3780 }