github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-rules-x86.ins (about) 1 /* 2 * jit-rules-x86.ins - Instruction selector for x86. 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 %regclass reg x86_reg 24 %regclass breg x86_breg 25 %regclass freg x86_freg 26 %lregclass lreg x86_lreg 27 28 /* 29 * Conversion opcodes. 30 */ 31 32 JIT_OP_TRUNC_SBYTE: 33 [=reg, breg] -> { 34 x86_widen_reg(inst, $1, $2, 1, 0); 35 } 36 37 JIT_OP_TRUNC_UBYTE: 38 [=reg, breg] -> { 39 x86_widen_reg(inst, $1, $2, 0, 0); 40 } 41 42 JIT_OP_TRUNC_SHORT: 43 [=reg, reg] -> { 44 x86_widen_reg(inst, $1, $2, 1, 1); 45 } 46 47 JIT_OP_TRUNC_USHORT: 48 [=reg, reg] -> { 49 x86_widen_reg(inst, $1, $2, 0, 1); 50 } 51 52 JIT_OP_CHECK_SBYTE: more_space 53 [reg] -> { 54 unsigned char *patch1; 55 unsigned char *patch2; 56 x86_alu_reg_imm(inst, X86_CMP, $1, -128); 57 patch1 = inst; 58 x86_branch8(inst, X86_CC_LE, 0, 1); 59 x86_alu_reg_imm(inst, X86_CMP, $1, 127); 60 patch2 = inst; 61 x86_branch8(inst, X86_CC_LE, 0, 1); 62 x86_patch(patch1, inst); 63 inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); 64 x86_patch(patch2, inst); 65 } 66 67 JIT_OP_CHECK_UBYTE: more_space 68 [reg] -> { 69 unsigned char *patch1; 70 x86_alu_reg_imm(inst, X86_CMP, $1, 256); 71 patch1 = inst; 72 x86_branch8(inst, X86_CC_LT, 0, 0); 73 inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); 74 x86_patch(patch1, inst); 75 } 76 77 JIT_OP_CHECK_SHORT: more_space 78 [reg] -> { 79 unsigned char *patch1; 80 unsigned char *patch2; 81 x86_alu_reg_imm(inst, X86_CMP, $1, -32768); 82 patch1 = inst; 83 x86_branch8(inst, X86_CC_LE, 0, 1); 84 x86_alu_reg_imm(inst, X86_CMP, $1, 32767); 85 patch2 = inst; 86 x86_branch8(inst, X86_CC_LE, 0, 1); 87 x86_patch(patch1, inst); 88 inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); 89 x86_patch(patch2, inst); 90 } 91 92 JIT_OP_CHECK_USHORT: more_space 93 [reg] -> { 94 unsigned char *patch1; 95 x86_alu_reg_imm(inst, X86_CMP, $1, 65536); 96 patch1 = inst; 97 x86_branch8(inst, X86_CC_LT, 0, 0); 98 inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); 99 x86_patch(patch1, inst); 100 } 101 102 JIT_OP_CHECK_INT, JIT_OP_CHECK_UINT: copy, more_space 103 [reg] -> { 104 unsigned char *patch1; 105 x86_alu_reg_imm(inst, X86_CMP, $1, 0); 106 patch1 = inst; 107 x86_branch8(inst, X86_CC_GE, 0, 1); 108 inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); 109 x86_patch(patch1, inst); 110 } 111 112 JIT_OP_LOW_WORD: 113 [=reg, imm] -> { 114 jit_uint value = ((jit_uint *)($2))[0]; 115 x86_mov_reg_imm(inst, $1, value); 116 } 117 [=reg, local] -> { 118 x86_mov_reg_membase(inst, $1, X86_EBP, $2, 4); 119 } 120 [=reg, lreg] -> { 121 if($1 != $2) 122 { 123 x86_mov_reg_reg(inst, $1, $2, 4); 124 } 125 } 126 127 JIT_OP_EXPAND_INT: 128 [=lreg, reg] -> { 129 if($1 != $2) 130 { 131 x86_mov_reg_reg(inst, $1, $2, 4); 132 } 133 x86_mov_reg_reg(inst, %1, $1, 4); 134 x86_shift_reg_imm(inst, X86_SAR, %1, 31); 135 } 136 137 JIT_OP_EXPAND_UINT: 138 [=lreg, reg] -> { 139 if($1 != $2) 140 { 141 x86_mov_reg_reg(inst, $1, $2, 4); 142 } 143 x86_clear_reg(inst, %1); 144 } 145 146 JIT_OP_FLOAT32_TO_INT, JIT_OP_FLOAT64_TO_INT, JIT_OP_NFLOAT_TO_INT: stack 147 [=reg, freg] -> { 148 /* allocate space on the stack for 2 shorts and 1 int */ 149 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 8); 150 /* store FPU control word */ 151 x86_fnstcw_membase(inst, X86_ESP, 0); 152 /* set "round toward zero" mode */ 153 x86_mov_reg_membase(inst, $1, X86_ESP, 0, 2); 154 x86_alu_reg16_imm(inst, X86_OR, $1, 0xc00); 155 x86_mov_membase_reg(inst, X86_ESP, 2, $1, 2); 156 x86_fldcw_membase(inst, X86_ESP, 2); 157 /* convert float to int */ 158 x86_fist_pop_membase(inst, X86_ESP, 4, 0); 159 /* restore FPU control word */ 160 x86_fldcw_membase(inst, X86_ESP, 0); 161 /* move result to the destination */ 162 x86_mov_reg_membase(inst, $1, X86_ESP, 4, 4); 163 /* restore the stack */ 164 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 8); 165 } 166 167 JIT_OP_FLOAT32_TO_LONG, JIT_OP_FLOAT64_TO_LONG, JIT_OP_NFLOAT_TO_LONG: stack 168 [=lreg, freg] -> { 169 /* allocate space on the stack for 2 shorts and 1 long */ 170 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 12); 171 /* store FPU control word */ 172 x86_fnstcw_membase(inst, X86_ESP, 0); 173 /* set "round toward zero" mode */ 174 x86_mov_reg_membase(inst, $1, X86_ESP, 0, 2); 175 x86_alu_reg16_imm(inst, X86_OR, $1, 0xc00); 176 x86_mov_membase_reg(inst, X86_ESP, 2, $1, 2); 177 x86_fldcw_membase(inst, X86_ESP, 2); 178 /* convert float to long */ 179 x86_fist_pop_membase(inst, X86_ESP, 4, 1); 180 /* restore FPU control word */ 181 x86_fldcw_membase(inst, X86_ESP, 0); 182 /* move result to the destination */ 183 x86_mov_reg_membase(inst, $1, X86_ESP, 4, 4); 184 x86_mov_reg_membase(inst, %1, X86_ESP, 8, 4); 185 /* restore the stack */ 186 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 12); 187 } 188 189 JIT_OP_INT_TO_FLOAT32: 190 [=freg, local] -> { 191 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(void *)); 192 x86_fild_membase(inst, X86_EBP, $2, 0); 193 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 194 x86_fld_membase(inst, X86_ESP, 0, 0); 195 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(void *)); 196 } 197 [=freg, reg] -> { 198 x86_push_reg(inst, $2); 199 x86_fild_membase(inst, X86_ESP, 0, 0); 200 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 201 x86_fld_membase(inst, X86_ESP, 0, 0); 202 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_nint)); 203 } 204 205 JIT_OP_INT_TO_FLOAT64, JIT_OP_INT_TO_NFLOAT: 206 [=freg, local] -> { 207 x86_fild_membase(inst, X86_EBP, $2, 0); 208 } 209 [=freg, reg] -> { 210 x86_push_reg(inst, $2); 211 x86_fild_membase(inst, X86_ESP, 0, 0); 212 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_nint)); 213 } 214 215 JIT_OP_UINT_TO_FLOAT32: 216 [=freg, reg, scratch reg] -> { 217 x86_clear_reg(inst, $3); 218 x86_push_reg(inst, $3); 219 x86_push_reg(inst, $2); 220 x86_fild_membase(inst, X86_ESP, 0, 1); 221 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 222 x86_fld_membase(inst, X86_ESP, 0, 0); 223 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 224 } 225 226 JIT_OP_UINT_TO_FLOAT64, JIT_OP_UINT_TO_NFLOAT: 227 [=freg, reg, scratch reg] -> { 228 x86_clear_reg(inst, $3); 229 x86_push_reg(inst, $3); 230 x86_push_reg(inst, $2); 231 x86_fild_membase(inst, X86_ESP, 0, 1); 232 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 233 } 234 235 JIT_OP_LONG_TO_FLOAT32: 236 [=freg, local] -> { 237 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float32)); 238 x86_fild_membase(inst, X86_EBP, $2, 1); 239 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 240 x86_fld_membase(inst, X86_ESP, 0, 0); 241 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float32)); 242 } 243 [=freg, lreg] -> { 244 x86_push_reg(inst, %2); 245 x86_push_reg(inst, $2); 246 x86_fild_membase(inst, X86_ESP, 0, 1); 247 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 248 x86_fld_membase(inst, X86_ESP, 0, 0); 249 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 250 } 251 252 JIT_OP_LONG_TO_FLOAT64: 253 [=freg, local] -> { 254 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64)); 255 x86_fild_membase(inst, X86_EBP, $2, 1); 256 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 257 x86_fld_membase(inst, X86_ESP, 0, 1); 258 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float64)); 259 } 260 [=freg, lreg] -> { 261 x86_push_reg(inst, %2); 262 x86_push_reg(inst, $2); 263 x86_fild_membase(inst, X86_ESP, 0, 1); 264 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 265 x86_fld_membase(inst, X86_ESP, 0, 1); 266 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 267 } 268 269 JIT_OP_LONG_TO_NFLOAT: 270 [=freg, local] -> { 271 x86_fild_membase(inst, X86_EBP, $2, 1); 272 } 273 [=freg, lreg] -> { 274 x86_push_reg(inst, %2); 275 x86_push_reg(inst, $2); 276 x86_fild_membase(inst, X86_ESP, 0, 1); 277 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 278 } 279 280 JIT_OP_ULONG_TO_FLOAT32, JIT_OP_ULONG_TO_FLOAT64, JIT_OP_ULONG_TO_NFLOAT: more_space 281 [=freg, lreg] -> { 282 /* TODO: review wrt relocation for elf pre-compilation */ 283 static float f2pow64; 284 static int inited; 285 unsigned char *patch; 286 if(!inited) 287 { 288 f2pow64 = jit_float32_pow(2.0, 64); 289 inited = 1; 290 } 291 x86_push_reg(inst, %2); 292 x86_push_reg(inst, $2); 293 x86_fild_membase(inst, X86_ESP, 0, 1); 294 x86_test_reg_reg(inst, %2, %2); 295 patch = inst; 296 x86_branch8(inst, X86_CC_NS, 0, 1); 297 x86_fp_op_mem(inst, X86_FADD, &f2pow64, 0); 298 x86_patch(patch, inst); 299 if(insn->opcode == JIT_OP_ULONG_TO_FLOAT32) 300 { 301 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 302 x86_fld_membase(inst, X86_ESP, 0, 0); 303 } 304 else if(insn->opcode == JIT_OP_ULONG_TO_FLOAT64) 305 { 306 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 307 x86_fld_membase(inst, X86_ESP, 0, 1); 308 } 309 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long)); 310 } 311 312 JIT_OP_FLOAT64_TO_FLOAT32, JIT_OP_NFLOAT_TO_FLOAT32: stack 313 [freg] -> { 314 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(void *)); 315 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 316 x86_fld_membase(inst, X86_ESP, 0, 0); 317 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(void *)); 318 } 319 320 JIT_OP_NFLOAT_TO_FLOAT64: stack 321 [freg] -> { 322 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64)); 323 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 324 x86_fld_membase(inst, X86_ESP, 0, 1); 325 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float64)); 326 } 327 328 JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT32_TO_FLOAT64, JIT_OP_FLOAT64_TO_NFLOAT: copy, stack 329 [freg] -> { 330 /* Nothing to do: loading the value onto the FP stack is sufficient */ 331 } 332 333 /* 334 * Arithmetic opcodes. 335 */ 336 337 JIT_OP_IADD: commutative 338 [reg, imm] -> { 339 x86_alu_reg_imm(inst, X86_ADD, $1, $2); 340 } 341 [reg, local] -> { 342 x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2); 343 } 344 [reg, reg] -> { 345 x86_alu_reg_reg(inst, X86_ADD, $1, $2); 346 } 347 348 JIT_OP_ISUB: 349 [reg, imm] -> { 350 x86_alu_reg_imm(inst, X86_SUB, $1, $2); 351 } 352 [reg, local] -> { 353 x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2); 354 } 355 [reg, reg] -> { 356 x86_alu_reg_reg(inst, X86_SUB, $1, $2); 357 } 358 359 JIT_OP_IMUL: commutative 360 [reg, imm] -> { 361 /* Handle special cases of immediate multiplies */ 362 switch($2) 363 { 364 case 0: 365 { 366 x86_clear_reg(inst, $1); 367 } 368 break; 369 370 case 1: break; 371 372 case -1: 373 { 374 x86_neg_reg(inst, $1); 375 } 376 break; 377 378 case 2: 379 { 380 x86_shift_reg_imm(inst, X86_SHL, $1, 1); 381 } 382 break; 383 384 case 3: 385 { 386 /* lea reg, [reg + reg * 2] */ 387 x86_lea_memindex(inst, $1, $1, 0, $1, 1); 388 } 389 break; 390 391 case 4: 392 { 393 x86_shift_reg_imm(inst, X86_SHL, $1, 2); 394 } 395 break; 396 397 case 5: 398 { 399 /* lea reg, [reg + reg * 4] */ 400 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 401 } 402 break; 403 404 case 6: 405 { 406 /* lea reg, [reg + reg * 2]; add reg, reg */ 407 x86_lea_memindex(inst, $1, $1, 0, $1, 1); 408 x86_alu_reg_reg(inst, X86_ADD, $1, $1); 409 } 410 break; 411 412 case 8: 413 { 414 x86_shift_reg_imm(inst, X86_SHL, $1, 3); 415 } 416 break; 417 418 case 9: 419 { 420 /* lea reg, [reg + reg * 8] */ 421 x86_lea_memindex(inst, $1, $1, 0, $1, 3); 422 } 423 break; 424 425 case 10: 426 { 427 /* lea reg, [reg + reg * 4]; add reg, reg */ 428 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 429 x86_alu_reg_reg(inst, X86_ADD, $1, $1); 430 } 431 break; 432 433 case 12: 434 { 435 /* lea reg, [reg + reg * 2]; shl reg, 2 */ 436 x86_lea_memindex(inst, $1, $1, 0, $1, 1); 437 x86_shift_reg_imm(inst, X86_SHL, $1, 2); 438 } 439 break; 440 441 case 16: 442 { 443 x86_shift_reg_imm(inst, X86_SHL, $1, 4); 444 } 445 break; 446 447 case 25: 448 { 449 /* lea reg, [reg + reg * 4]; lea reg, [reg + reg * 4] */ 450 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 451 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 452 } 453 break; 454 455 case 32: 456 { 457 x86_shift_reg_imm(inst, X86_SHL, $1, 5); 458 } 459 break; 460 461 case 64: 462 { 463 x86_shift_reg_imm(inst, X86_SHL, $1, 6); 464 } 465 break; 466 467 case 100: 468 { 469 /* lea reg, [reg + reg * 4]; shl reg, 2; 470 lea reg, [reg + reg * 4] */ 471 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 472 x86_shift_reg_imm(inst, X86_SHL, $1, 2); 473 x86_lea_memindex(inst, $1, $1, 0, $1, 2); 474 } 475 break; 476 477 case 128: 478 { 479 x86_shift_reg_imm(inst, X86_SHL, $1, 7); 480 } 481 break; 482 483 case 256: 484 { 485 x86_shift_reg_imm(inst, X86_SHL, $1, 8); 486 } 487 break; 488 489 case 512: 490 { 491 x86_shift_reg_imm(inst, X86_SHL, $1, 9); 492 } 493 break; 494 495 case 1024: 496 { 497 x86_shift_reg_imm(inst, X86_SHL, $1, 10); 498 } 499 break; 500 501 case 2048: 502 { 503 x86_shift_reg_imm(inst, X86_SHL, $1, 11); 504 } 505 break; 506 507 case 4096: 508 { 509 x86_shift_reg_imm(inst, X86_SHL, $1, 12); 510 } 511 break; 512 513 case 8192: 514 { 515 x86_shift_reg_imm(inst, X86_SHL, $1, 13); 516 } 517 break; 518 519 case 16384: 520 { 521 x86_shift_reg_imm(inst, X86_SHL, $1, 14); 522 } 523 break; 524 525 case 32768: 526 { 527 x86_shift_reg_imm(inst, X86_SHL, $1, 15); 528 } 529 break; 530 531 case 65536: 532 { 533 x86_shift_reg_imm(inst, X86_SHL, $1, 16); 534 } 535 break; 536 537 case 0x00020000: 538 { 539 x86_shift_reg_imm(inst, X86_SHL, $1, 17); 540 } 541 break; 542 543 case 0x00040000: 544 { 545 x86_shift_reg_imm(inst, X86_SHL, $1, 18); 546 } 547 break; 548 549 case 0x00080000: 550 { 551 x86_shift_reg_imm(inst, X86_SHL, $1, 19); 552 } 553 break; 554 555 case 0x00100000: 556 { 557 x86_shift_reg_imm(inst, X86_SHL, $1, 20); 558 } 559 break; 560 561 case 0x00200000: 562 { 563 x86_shift_reg_imm(inst, X86_SHL, $1, 21); 564 } 565 break; 566 567 case 0x00400000: 568 { 569 x86_shift_reg_imm(inst, X86_SHL, $1, 22); 570 } 571 break; 572 573 case 0x00800000: 574 { 575 x86_shift_reg_imm(inst, X86_SHL, $1, 23); 576 } 577 break; 578 579 case 0x01000000: 580 { 581 x86_shift_reg_imm(inst, X86_SHL, $1, 24); 582 } 583 break; 584 585 case 0x02000000: 586 { 587 x86_shift_reg_imm(inst, X86_SHL, $1, 25); 588 } 589 break; 590 591 case 0x04000000: 592 { 593 x86_shift_reg_imm(inst, X86_SHL, $1, 26); 594 } 595 break; 596 597 case 0x08000000: 598 { 599 x86_shift_reg_imm(inst, X86_SHL, $1, 27); 600 } 601 break; 602 603 case 0x10000000: 604 { 605 x86_shift_reg_imm(inst, X86_SHL, $1, 28); 606 } 607 break; 608 609 case 0x20000000: 610 { 611 x86_shift_reg_imm(inst, X86_SHL, $1, 29); 612 } 613 break; 614 615 case 0x40000000: 616 { 617 x86_shift_reg_imm(inst, X86_SHL, $1, 30); 618 } 619 break; 620 621 case (jit_nint)0x80000000: 622 { 623 x86_shift_reg_imm(inst, X86_SHL, $1, 31); 624 } 625 break; 626 627 default: 628 { 629 x86_imul_reg_reg_imm(inst, $1, $1, $2); 630 } 631 break; 632 } 633 } 634 [reg, local] -> { 635 x86_imul_reg_membase(inst, $1, X86_EBP, $2); 636 } 637 [reg, reg] -> { 638 x86_imul_reg_reg(inst, $1, $2); 639 } 640 641 JIT_OP_IDIV: more_space 642 [any, immzero] -> { 643 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 644 } 645 [reg, imm, if("$2 == 1")] -> { 646 } 647 [reg, imm, if("$2 == -1")] -> { 648 /* Dividing by -1 gives an exception if the argument 649 is minint, or simply negates for other values */ 650 unsigned char *patch; 651 x86_alu_reg_imm(inst, X86_CMP, $1, jit_min_int); 652 patch = inst; 653 x86_branch8(inst, X86_CC_NE, 0, 0); 654 inst = throw_builtin(inst, func, JIT_RESULT_ARITHMETIC); 655 x86_patch(patch, inst); 656 x86_neg_reg(inst, $1); 657 } 658 [reg, imm, scratch reg, if("$2 == 2")] -> { 659 x86_mov_reg_reg(inst, $3, $1, 4); 660 x86_shift_reg_imm(inst, X86_SHR, $3, 0x1f); 661 x86_alu_reg_reg(inst, X86_ADD, $1, $3); 662 x86_shift_reg_imm(inst, X86_SAR, $1, 1); 663 } 664 [reg, imm, scratch reg, if("($2 > 0) && (((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> { 665 /* x & (x - 1) is equal to zero if x is a power of 2 */ 666 /* This code is generated by gcc for pentium. */ 667 /* We use this code because cmov is not available on all i386 cpus */ 668 jit_nuint shift, temp, value = $2 >> 1; 669 for(shift = 0; value; value >>= 1) 670 { 671 ++shift; 672 } 673 temp = 32 - shift; 674 x86_mov_reg_reg(inst, $3, $1, 4); 675 x86_shift_reg_imm(inst, X86_SAR, $3, 0x1f); 676 x86_shift_reg_imm(inst, X86_SHR, $3, temp); 677 x86_alu_reg_reg(inst, X86_ADD, $1, $3); 678 x86_shift_reg_imm(inst, X86_SAR, $1, shift); 679 } 680 [reg("eax"), imm, scratch reg, scratch reg("edx")] -> { 681 x86_mov_reg_imm(inst, $3, $2); 682 x86_cdq(inst); 683 x86_div_reg(inst, $3, 1); 684 } 685 [reg("eax"), reg, scratch reg("edx")] -> { 686 unsigned char *patch, *patch2; 687 #ifndef JIT_USE_SIGNALS 688 x86_alu_reg_reg(inst, X86_OR, $2, $2); 689 patch = inst; 690 x86_branch8(inst, X86_CC_NE, 0, 0); 691 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 692 x86_patch(patch, inst); 693 #endif 694 x86_alu_reg_imm(inst, X86_CMP, $2, -1); 695 patch = inst; 696 x86_branch8(inst, X86_CC_NE, 0, 0); 697 x86_alu_reg_imm(inst, X86_CMP, $1, jit_min_int); 698 patch2 = inst; 699 x86_branch8(inst, X86_CC_NE, 0, 0); 700 inst = throw_builtin(inst, func, JIT_RESULT_ARITHMETIC); 701 x86_patch(patch, inst); 702 x86_patch(patch2, inst); 703 x86_cdq(inst); 704 x86_div_reg(inst, $2, 1); 705 } 706 707 JIT_OP_IDIV_UN: more_space 708 [any, immzero] -> { 709 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 710 } 711 [reg, imm, if("$2 == 1")] -> { 712 } 713 [reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> { 714 /* x & (x - 1) is equal to zero if x is a power of 2 */ 715 jit_nuint shift, value = $2 >> 1; 716 for(shift = 0; value; value >>= 1) 717 { 718 ++shift; 719 } 720 x86_shift_reg_imm(inst, X86_SHR, $1, shift); 721 } 722 [reg("eax"), imm, scratch reg, scratch reg("edx")] -> { 723 x86_mov_reg_imm(inst, $3, $2); 724 x86_clear_reg(inst, X86_EDX); 725 x86_div_reg(inst, $3, 0); 726 } 727 [reg("eax"), reg, scratch reg("edx")] -> { 728 #ifndef JIT_USE_SIGNALS 729 unsigned char *patch; 730 x86_alu_reg_reg(inst, X86_OR, $2, $2); 731 patch = inst; 732 x86_branch8(inst, X86_CC_NE, 0, 0); 733 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 734 x86_patch(patch, inst); 735 #endif 736 x86_clear_reg(inst, X86_EDX); 737 x86_div_reg(inst, $2, 0); 738 } 739 740 JIT_OP_IREM: more_space 741 [any, immzero] -> { 742 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 743 } 744 [reg, imm, if("$2 == 1")] -> { 745 x86_clear_reg(inst, $1); 746 } 747 [reg, imm, if("$2 == -1")] -> { 748 /* Dividing by -1 gives an exception if the argument 749 is minint, or simply gives a remainder of zero */ 750 unsigned char *patch; 751 x86_alu_reg_imm(inst, X86_CMP, $1, jit_min_int); 752 patch = inst; 753 x86_branch8(inst, X86_CC_NE, 0, 0); 754 inst = throw_builtin(inst, func, JIT_RESULT_ARITHMETIC); 755 x86_patch(patch, inst); 756 x86_clear_reg(inst, $1); 757 } 758 [=reg("edx"), *reg("eax"), imm, scratch reg, scratch reg("edx")] -> { 759 x86_mov_reg_imm(inst, $4, $3); 760 x86_cdq(inst); 761 x86_div_reg(inst, $4, 1); 762 } 763 [=reg("edx"), *reg("eax"), reg, scratch reg("edx")] -> { 764 unsigned char *patch, *patch2; 765 #ifndef JIT_USE_SIGNALS 766 x86_alu_reg_reg(inst, X86_OR, $3, $3); 767 patch = inst; 768 x86_branch8(inst, X86_CC_NE, 0, 0); 769 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 770 x86_patch(patch, inst); 771 #endif 772 x86_alu_reg_imm(inst, X86_CMP, $3, -1); 773 patch = inst; 774 x86_branch8(inst, X86_CC_NE, 0, 0); 775 x86_alu_reg_imm(inst, X86_CMP, $2, jit_min_int); 776 patch2 = inst; 777 x86_branch8(inst, X86_CC_NE, 0, 0); 778 inst = throw_builtin(inst, func, JIT_RESULT_ARITHMETIC); 779 x86_patch(patch, inst); 780 x86_patch(patch2, inst); 781 x86_cdq(inst); 782 x86_div_reg(inst, $3, 1); 783 } 784 785 JIT_OP_IREM_UN: more_space 786 [any, immzero] -> { 787 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 788 } 789 [reg, imm, if("$2 == 1")] -> { 790 x86_clear_reg(inst, $1); 791 } 792 [reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> { 793 /* x & (x - 1) is equal to zero if x is a power of 2 */ 794 x86_alu_reg_imm(inst, X86_AND, $1, $2 - 1); 795 } 796 [=reg("edx"), *reg("eax"), imm, scratch reg, scratch reg("edx")] -> { 797 x86_mov_reg_imm(inst, $4, $3); 798 x86_clear_reg(inst, X86_EDX); 799 x86_div_reg(inst, $4, 0); 800 } 801 [=reg("edx"), *reg("eax"), reg, scratch reg("edx")] -> { 802 #ifndef JIT_USE_SIGNALS 803 unsigned char *patch; 804 x86_alu_reg_reg(inst, X86_OR, $3, $3); 805 patch = inst; 806 x86_branch8(inst, X86_CC_NE, 0, 0); 807 inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); 808 x86_patch(patch, inst); 809 #endif 810 x86_clear_reg(inst, X86_EDX); 811 x86_div_reg(inst, $3, 0); 812 } 813 814 JIT_OP_INEG: 815 [reg] -> { 816 x86_neg_reg(inst, $1); 817 } 818 819 JIT_OP_LADD: commutative 820 [lreg, imm] -> { 821 jit_int value1 = ((jit_int *)($2))[0]; 822 jit_int value2 = ((jit_int *)($2))[1]; 823 if(value1 != 0) 824 { 825 x86_alu_reg_imm(inst, X86_ADD, $1, value1); 826 x86_alu_reg_imm(inst, X86_ADC, %1, value2); 827 } 828 else 829 { 830 x86_alu_reg_imm(inst, X86_ADD, %1, value2); 831 } 832 } 833 [lreg, local] -> { 834 x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2); 835 x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2 + 4); 836 } 837 [lreg, lreg] -> { 838 x86_alu_reg_reg(inst, X86_ADD, $1, $2); 839 x86_alu_reg_reg(inst, X86_ADC, %1, %2); 840 } 841 842 JIT_OP_LSUB: 843 [lreg, imm] -> { 844 jit_int value1 = ((jit_int *)($2))[0]; 845 jit_int value2 = ((jit_int *)($2))[1]; 846 if(value1 != 0) 847 { 848 x86_alu_reg_imm(inst, X86_SUB, $1, value1); 849 x86_alu_reg_imm(inst, X86_SBB, %1, value2); 850 } 851 else 852 { 853 x86_alu_reg_imm(inst, X86_SUB, %1, value2); 854 } 855 } 856 [lreg, local] -> { 857 x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2); 858 x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2 + 4); 859 } 860 [lreg, lreg] -> { 861 x86_alu_reg_reg(inst, X86_SUB, $1, $2); 862 x86_alu_reg_reg(inst, X86_SBB, %1, %2); 863 } 864 865 JIT_OP_LNEG: 866 [lreg] -> { 867 /* TODO: gcc generates the first variant while 868 AoA suggests the second. Figure out if one 869 is better than other. */ 870 #if 1 871 x86_neg_reg(inst, $1); 872 x86_alu_reg_imm(inst, X86_ADC, %1, 0); 873 x86_neg_reg(inst, %1); 874 #else 875 x86_neg_reg(inst, %1); 876 x86_neg_reg(inst, $1); 877 x86_alu_reg_imm(inst, X86_SBB, %1, 0); 878 #endif 879 } 880 881 JIT_OP_FADD, JIT_OP_DADD, JIT_OP_NFADD: stack, x87_arith, commutative 882 [freg, freg] -> { 883 int flags; 884 885 flags = _jit_regs_select(®s); 886 887 if((flags & _JIT_REGS_NO_POP) == 0) 888 { 889 x86_fp_op_reg(inst, X86_FADD, 890 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1); 891 } 892 else if((flags & _JIT_REGS_FLIP_ARGS) != 0) 893 { 894 x86_fp_op_reg(inst, X86_FADD, 895 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0); 896 } 897 else 898 { 899 x86_fp_op(inst, X86_FADD, 900 fp_stack_index(gen, $2 + JIT_REG_STACK_START)); 901 } 902 } 903 904 JIT_OP_FSUB, JIT_OP_DSUB, JIT_OP_NFSUB: stack, x87_arith_reversible 905 [freg, freg] -> { 906 int flags; 907 908 flags = _jit_regs_select(®s); 909 910 if((flags & _JIT_REGS_NO_POP) == 0) 911 { 912 if((flags & _JIT_REGS_REVERSE) == 0) 913 { 914 x86_fp_op_reg(inst, X86_FSUB, 915 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1); 916 } 917 else 918 { 919 x86_fp_op_reg(inst, X86_FSUBR, 920 fp_stack_index(gen, $2 + JIT_REG_STACK_START), 1); 921 } 922 } 923 else if((flags & _JIT_REGS_FLIP_ARGS) != 0) 924 { 925 if((flags & _JIT_REGS_REVERSE) == 0) 926 { 927 x86_fp_op_reg(inst, X86_FSUB, 928 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0); 929 } 930 else 931 { 932 x86_fp_op(inst, X86_FSUBR, 933 fp_stack_index(gen, $1 + JIT_REG_STACK_START)); 934 } 935 } 936 else 937 { 938 if((flags & _JIT_REGS_REVERSE) == 0) 939 { 940 x86_fp_op(inst, X86_FSUB, 941 fp_stack_index(gen, $2 + JIT_REG_STACK_START)); 942 } 943 else 944 { 945 x86_fp_op_reg(inst, X86_FSUBR, 946 fp_stack_index(gen, $2 + JIT_REG_STACK_START), 0); 947 } 948 } 949 } 950 951 JIT_OP_FMUL, JIT_OP_DMUL, JIT_OP_NFMUL: stack, x87_arith, commutative 952 [freg, freg] -> { 953 int flags; 954 955 flags = _jit_regs_select(®s); 956 957 if((flags & _JIT_REGS_NO_POP) == 0) 958 { 959 x86_fp_op_reg(inst, X86_FMUL, fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1); 960 } 961 else if((flags & _JIT_REGS_FLIP_ARGS) != 0) 962 { 963 x86_fp_op_reg(inst, X86_FMUL, fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0); 964 } 965 else 966 { 967 x86_fp_op(inst, X86_FMUL, fp_stack_index(gen, $2 + JIT_REG_STACK_START)); 968 } 969 } 970 971 JIT_OP_FDIV, JIT_OP_DDIV, JIT_OP_NFDIV: stack, x87_arith_reversible 972 [freg, freg] -> { 973 int flags; 974 975 flags = _jit_regs_select(®s); 976 977 if((flags & _JIT_REGS_NO_POP) == 0) 978 { 979 if((flags & _JIT_REGS_REVERSE) == 0) 980 { 981 x86_fp_op_reg(inst, X86_FDIV, 982 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1); 983 } 984 else 985 { 986 x86_fp_op_reg(inst, X86_FDIVR, 987 fp_stack_index(gen, $2 + JIT_REG_STACK_START), 1); 988 } 989 } 990 else if((flags & _JIT_REGS_FLIP_ARGS) != 0) 991 { 992 if((flags & _JIT_REGS_REVERSE) == 0) 993 { 994 x86_fp_op_reg(inst, X86_FDIV, 995 fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0); 996 } 997 else 998 { 999 x86_fp_op(inst, X86_FDIVR, 1000 fp_stack_index(gen, $1 + JIT_REG_STACK_START)); 1001 } 1002 } 1003 else 1004 { 1005 if((flags & _JIT_REGS_REVERSE) == 0) 1006 { 1007 x86_fp_op(inst, X86_FDIV, 1008 fp_stack_index(gen, $2 + JIT_REG_STACK_START)); 1009 } 1010 else 1011 { 1012 x86_fp_op_reg(inst, X86_FDIVR, 1013 fp_stack_index(gen, $2 + JIT_REG_STACK_START), 0); 1014 } 1015 } 1016 } 1017 1018 JIT_OP_FREM, JIT_OP_DREM, JIT_OP_NFREM: stack 1019 [freg, freg, scratch reg("eax")] -> { 1020 unsigned char *label; 1021 label = inst; 1022 x86_fprem(inst); 1023 x86_fnstsw(inst); 1024 x86_alu_reg_imm(inst, X86_AND, X86_EAX, 0x0400); 1025 x86_branch(inst, X86_CC_NZ, label, 0); 1026 x86_fstp(inst, 1); 1027 } 1028 1029 JIT_OP_FNEG, JIT_OP_DNEG, JIT_OP_NFNEG: stack 1030 [freg] -> { 1031 x86_fchs(inst); 1032 } 1033 1034 /* 1035 * Bitwise opcodes. 1036 */ 1037 1038 JIT_OP_IAND: commutative 1039 [reg, imm] -> { 1040 x86_alu_reg_imm(inst, X86_AND, $1, $2); 1041 } 1042 [reg, local] -> { 1043 x86_alu_reg_membase(inst, X86_AND, $1, X86_EBP, $2); 1044 } 1045 [reg, reg] -> { 1046 x86_alu_reg_reg(inst, X86_AND, $1, $2); 1047 } 1048 1049 JIT_OP_IOR: commutative 1050 [reg, imm] -> { 1051 x86_alu_reg_imm(inst, X86_OR, $1, $2); 1052 } 1053 [reg, local] -> { 1054 x86_alu_reg_membase(inst, X86_OR, $1, X86_EBP, $2); 1055 } 1056 [reg, reg] -> { 1057 x86_alu_reg_reg(inst, X86_OR, $1, $2); 1058 } 1059 1060 JIT_OP_IXOR: commutative 1061 [reg, imm] -> { 1062 x86_alu_reg_imm(inst, X86_XOR, $1, $2); 1063 } 1064 [reg, local] -> { 1065 x86_alu_reg_membase(inst, X86_XOR, $1, X86_EBP, $2); 1066 } 1067 [reg, reg] -> { 1068 x86_alu_reg_reg(inst, X86_XOR, $1, $2); 1069 } 1070 1071 JIT_OP_INOT: 1072 [reg] -> { 1073 x86_not_reg(inst, $1); 1074 } 1075 1076 JIT_OP_ISHL: 1077 [reg, imm] -> { 1078 x86_shift_reg_imm(inst, X86_SHL, $1, ($2 & 0x1F)); 1079 } 1080 [reg, reg("ecx")] -> { 1081 x86_shift_reg(inst, X86_SHL, $1); 1082 } 1083 1084 JIT_OP_ISHR: 1085 [reg, imm] -> { 1086 x86_shift_reg_imm(inst, X86_SAR, $1, ($2 & 0x1F)); 1087 } 1088 [reg, reg("ecx")] -> { 1089 x86_shift_reg(inst, X86_SAR, $1); 1090 } 1091 1092 JIT_OP_ISHR_UN: 1093 [reg, imm] -> { 1094 x86_shift_reg_imm(inst, X86_SHR, $1, ($2 & 0x1F)); 1095 } 1096 [reg, reg("ecx")] -> { 1097 x86_shift_reg(inst, X86_SHR, $1); 1098 } 1099 1100 JIT_OP_LAND: commutative 1101 [lreg, imm] -> { 1102 jit_int value1 = ((jit_int *)($2))[0]; 1103 jit_int value2 = ((jit_int *)($2))[1]; 1104 x86_alu_reg_imm(inst, X86_AND, $1, value1); 1105 x86_alu_reg_imm(inst, X86_AND, %1, value2); 1106 } 1107 [lreg, local] -> { 1108 x86_alu_reg_membase(inst, X86_AND, $1, X86_EBP, $2); 1109 x86_alu_reg_membase(inst, X86_AND, %1, X86_EBP, $2 + 4); 1110 } 1111 [lreg, lreg] -> { 1112 x86_alu_reg_reg(inst, X86_AND, $1, $2); 1113 x86_alu_reg_reg(inst, X86_AND, %1, %2); 1114 } 1115 1116 JIT_OP_LOR: commutative 1117 [lreg, imm] -> { 1118 jit_int value1 = ((jit_int *)($2))[0]; 1119 jit_int value2 = ((jit_int *)($2))[1]; 1120 x86_alu_reg_imm(inst, X86_OR, $1, value1); 1121 x86_alu_reg_imm(inst, X86_OR, %1, value2); 1122 } 1123 [lreg, local] -> { 1124 x86_alu_reg_membase(inst, X86_OR, $1, X86_EBP, $2); 1125 x86_alu_reg_membase(inst, X86_OR, %1, X86_EBP, $2 + 4); 1126 } 1127 [lreg, lreg] -> { 1128 x86_alu_reg_reg(inst, X86_OR, $1, $2); 1129 x86_alu_reg_reg(inst, X86_OR, %1, %2); 1130 } 1131 1132 JIT_OP_LXOR: commutative 1133 [lreg, imm] -> { 1134 jit_int value1 = ((jit_int *)($2))[0]; 1135 jit_int value2 = ((jit_int *)($2))[1]; 1136 x86_alu_reg_imm(inst, X86_XOR, $1, value1); 1137 x86_alu_reg_imm(inst, X86_XOR, %1, value2); 1138 } 1139 [lreg, local] -> { 1140 x86_alu_reg_membase(inst, X86_XOR, $1, X86_EBP, $2); 1141 x86_alu_reg_membase(inst, X86_XOR, %1, X86_EBP, $2 + 4); 1142 } 1143 [lreg, lreg] -> { 1144 x86_alu_reg_reg(inst, X86_XOR, $1, $2); 1145 x86_alu_reg_reg(inst, X86_XOR, %1, %2); 1146 } 1147 1148 JIT_OP_LNOT: 1149 [lreg] -> { 1150 x86_not_reg(inst, $1); 1151 x86_not_reg(inst, %1); 1152 } 1153 1154 /* 1155 * Branch opcodes. 1156 */ 1157 1158 JIT_OP_BR: branch 1159 [] -> { 1160 inst = output_branch(func, inst, 0xEB /* jmp */, insn); 1161 } 1162 1163 JIT_OP_BR_IFALSE: branch 1164 [reg] -> { 1165 x86_alu_reg_reg(inst, X86_OR, $1, $1); 1166 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1167 } 1168 1169 JIT_OP_BR_ITRUE: branch 1170 [reg] -> { 1171 x86_alu_reg_reg(inst, X86_OR, $1, $1); 1172 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1173 } 1174 1175 JIT_OP_BR_IEQ: branch 1176 [reg, immzero] -> { 1177 x86_alu_reg_reg(inst, X86_OR, $1, $1); 1178 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1179 } 1180 [reg, imm] -> { 1181 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1182 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1183 } 1184 [reg, local] -> { 1185 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1186 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1187 } 1188 [reg, reg] -> { 1189 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1190 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1191 } 1192 1193 JIT_OP_BR_INE: branch 1194 [reg, immzero] -> { 1195 x86_alu_reg_reg(inst, X86_OR, $1, $1); 1196 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1197 } 1198 [reg, imm] -> { 1199 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1200 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1201 } 1202 [reg, local] -> { 1203 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1204 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1205 } 1206 [reg, reg] -> { 1207 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1208 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1209 } 1210 1211 JIT_OP_BR_ILT: branch 1212 [reg, imm] -> { 1213 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1214 inst = output_branch(func, inst, 0x7C /* lt */, insn); 1215 } 1216 [reg, local] -> { 1217 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1218 inst = output_branch(func, inst, 0x7C /* lt */, insn); 1219 } 1220 [reg, reg] -> { 1221 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1222 inst = output_branch(func, inst, 0x7C /* lt */, insn); 1223 } 1224 1225 JIT_OP_BR_ILT_UN: branch 1226 [reg, imm] -> { 1227 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1228 inst = output_branch(func, inst, 0x72 /* lt_un */, insn); 1229 } 1230 [reg, local] -> { 1231 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1232 inst = output_branch(func, inst, 0x72 /* lt_un */, insn); 1233 } 1234 [reg, reg] -> { 1235 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1236 inst = output_branch(func, inst, 0x72 /* lt_un */, insn); 1237 } 1238 1239 JIT_OP_BR_ILE: branch 1240 [reg, imm] -> { 1241 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1242 inst = output_branch(func, inst, 0x7E /* le */, insn); 1243 } 1244 [reg, local] -> { 1245 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1246 inst = output_branch(func, inst, 0x7E /* le */, insn); 1247 } 1248 [reg, reg] -> { 1249 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1250 inst = output_branch(func, inst, 0x7E /* le */, insn); 1251 } 1252 1253 JIT_OP_BR_ILE_UN: branch 1254 [reg, imm] -> { 1255 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1256 inst = output_branch(func, inst, 0x76 /* le_un */, insn); 1257 } 1258 [reg, local] -> { 1259 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1260 inst = output_branch(func, inst, 0x76 /* le_un */, insn); 1261 } 1262 [reg, reg] -> { 1263 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1264 inst = output_branch(func, inst, 0x76 /* le_un */, insn); 1265 } 1266 1267 JIT_OP_BR_IGT: branch 1268 [reg, imm] -> { 1269 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1270 inst = output_branch(func, inst, 0x7F /* gt */, insn); 1271 } 1272 [reg, local] -> { 1273 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1274 inst = output_branch(func, inst, 0x7F /* gt */, insn); 1275 } 1276 [reg, reg] -> { 1277 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1278 inst = output_branch(func, inst, 0x7F /* gt */, insn); 1279 } 1280 1281 JIT_OP_BR_IGT_UN: branch 1282 [reg, imm] -> { 1283 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1284 inst = output_branch(func, inst, 0x77 /* gt_un */, insn); 1285 } 1286 [reg, local] -> { 1287 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1288 inst = output_branch(func, inst, 0x77 /* gt_un */, insn); 1289 } 1290 [reg, reg] -> { 1291 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1292 inst = output_branch(func, inst, 0x77 /* gt_un */, insn); 1293 } 1294 1295 JIT_OP_BR_IGE: branch 1296 [reg, imm] -> { 1297 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1298 inst = output_branch(func, inst, 0x7D /* ge */, insn); 1299 } 1300 [reg, local] -> { 1301 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1302 inst = output_branch(func, inst, 0x7D /* ge */, insn); 1303 } 1304 [reg, reg] -> { 1305 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1306 inst = output_branch(func, inst, 0x7D /* ge */, insn); 1307 } 1308 1309 JIT_OP_BR_IGE_UN: branch 1310 [reg, imm] -> { 1311 x86_alu_reg_imm(inst, X86_CMP, $1, $2); 1312 inst = output_branch(func, inst, 0x73 /* ge_un */, insn); 1313 } 1314 [reg, local] -> { 1315 x86_alu_reg_membase(inst, X86_CMP, $1, X86_EBP, $2); 1316 inst = output_branch(func, inst, 0x73 /* ge_un */, insn); 1317 } 1318 [reg, reg] -> { 1319 x86_alu_reg_reg(inst, X86_CMP, $1, $2); 1320 inst = output_branch(func, inst, 0x73 /* ge_un */, insn); 1321 } 1322 1323 JIT_OP_BR_LFALSE: branch 1324 [lreg] -> { 1325 x86_alu_reg_reg(inst, X86_OR, $1, %1); 1326 inst = output_branch(func, inst, 0x74 /* eq */, insn); 1327 } 1328 1329 JIT_OP_BR_LTRUE: branch 1330 [lreg] -> { 1331 x86_alu_reg_reg(inst, X86_OR, $1, %1); 1332 inst = output_branch(func, inst, 0x75 /* ne */, insn); 1333 } 1334 1335 /* 1336 * Comparison opcodes. 1337 */ 1338 1339 JIT_OP_IEQ: 1340 [=reg, reg, immzero] -> { 1341 x86_alu_reg_reg(inst, X86_OR, $2, $2); 1342 inst = setcc_reg(inst, $1, X86_CC_EQ, 0); 1343 } 1344 [=reg, reg, imm] -> { 1345 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1346 inst = setcc_reg(inst, $1, X86_CC_EQ, 0); 1347 } 1348 [=reg, reg, local] -> { 1349 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1350 inst = setcc_reg(inst, $1, X86_CC_EQ, 0); 1351 } 1352 [=reg, reg, reg] -> { 1353 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1354 inst = setcc_reg(inst, $1, X86_CC_EQ, 0); 1355 } 1356 1357 JIT_OP_INE: 1358 [=reg, reg, immzero] -> { 1359 x86_alu_reg_reg(inst, X86_OR, $2, $2); 1360 inst = setcc_reg(inst, $1, X86_CC_NE, 0); 1361 } 1362 [=reg, reg, imm] -> { 1363 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1364 inst = setcc_reg(inst, $1, X86_CC_NE, 0); 1365 } 1366 [=reg, reg, local] -> { 1367 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1368 inst = setcc_reg(inst, $1, X86_CC_NE, 0); 1369 } 1370 [=reg, reg, reg] -> { 1371 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1372 inst = setcc_reg(inst, $1, X86_CC_NE, 0); 1373 } 1374 1375 JIT_OP_ILT: 1376 [=reg, reg, imm] -> { 1377 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1378 inst = setcc_reg(inst, $1, X86_CC_LT, 1); 1379 } 1380 [=reg, reg, local] -> { 1381 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1382 inst = setcc_reg(inst, $1, X86_CC_LT, 1); 1383 } 1384 [=reg, reg, reg] -> { 1385 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1386 inst = setcc_reg(inst, $1, X86_CC_LT, 1); 1387 } 1388 1389 JIT_OP_ILT_UN: 1390 [=reg, reg, imm] -> { 1391 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1392 inst = setcc_reg(inst, $1, X86_CC_LT, 0); 1393 } 1394 [=reg, reg, local] -> { 1395 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1396 inst = setcc_reg(inst, $1, X86_CC_LT, 0); 1397 } 1398 [=reg, reg, reg] -> { 1399 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1400 inst = setcc_reg(inst, $1, X86_CC_LT, 0); 1401 } 1402 1403 JIT_OP_ILE: 1404 [=reg, reg, imm] -> { 1405 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1406 inst = setcc_reg(inst, $1, X86_CC_LE, 1); 1407 } 1408 [=reg, reg, local] -> { 1409 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1410 inst = setcc_reg(inst, $1, X86_CC_LE, 1); 1411 } 1412 [=reg, reg, reg] -> { 1413 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1414 inst = setcc_reg(inst, $1, X86_CC_LE, 1); 1415 } 1416 1417 JIT_OP_ILE_UN: 1418 [=reg, reg, imm] -> { 1419 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1420 inst = setcc_reg(inst, $1, X86_CC_LE, 0); 1421 } 1422 [=reg, reg, local] -> { 1423 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1424 inst = setcc_reg(inst, $1, X86_CC_LE, 0); 1425 } 1426 [=reg, reg, reg] -> { 1427 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1428 inst = setcc_reg(inst, $1, X86_CC_LE, 0); 1429 } 1430 1431 JIT_OP_IGT: 1432 [=reg, reg, imm] -> { 1433 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1434 inst = setcc_reg(inst, $1, X86_CC_GT, 1); 1435 } 1436 [=reg, reg, local] -> { 1437 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1438 inst = setcc_reg(inst, $1, X86_CC_GT, 1); 1439 } 1440 [=reg, reg, reg] -> { 1441 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1442 inst = setcc_reg(inst, $1, X86_CC_GT, 1); 1443 } 1444 1445 JIT_OP_IGT_UN: 1446 [=reg, reg, imm] -> { 1447 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1448 inst = setcc_reg(inst, $1, X86_CC_GT, 0); 1449 } 1450 [=reg, reg, local] -> { 1451 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1452 inst = setcc_reg(inst, $1, X86_CC_GT, 0); 1453 } 1454 [=reg, reg, reg] -> { 1455 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1456 inst = setcc_reg(inst, $1, X86_CC_GT, 0); 1457 } 1458 1459 JIT_OP_IGE: 1460 [=reg, reg, imm] -> { 1461 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1462 inst = setcc_reg(inst, $1, X86_CC_GE, 1); 1463 } 1464 [=reg, reg, local] -> { 1465 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1466 inst = setcc_reg(inst, $1, X86_CC_GE, 1); 1467 } 1468 [=reg, reg, reg] -> { 1469 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1470 inst = setcc_reg(inst, $1, X86_CC_GE, 1); 1471 } 1472 1473 JIT_OP_IGE_UN: 1474 [=reg, reg, imm] -> { 1475 x86_alu_reg_imm(inst, X86_CMP, $2, $3); 1476 inst = setcc_reg(inst, $1, X86_CC_GE, 0); 1477 } 1478 [=reg, reg, local] -> { 1479 x86_alu_reg_membase(inst, X86_CMP, $2, X86_EBP, $3); 1480 inst = setcc_reg(inst, $1, X86_CC_GE, 0); 1481 } 1482 [=reg, reg, reg] -> { 1483 x86_alu_reg_reg(inst, X86_CMP, $2, $3); 1484 inst = setcc_reg(inst, $1, X86_CC_GE, 0); 1485 } 1486 1487 /* 1488 * Mathematical opcodes. 1489 */ 1490 1491 JIT_OP_FATAN, JIT_OP_DATAN, JIT_OP_NFATAN: stack 1492 [freg, scratch freg] -> { 1493 x86_fld1(inst); 1494 x86_fpatan(inst); 1495 x86_fldz(inst); 1496 x86_fp_op_reg(inst, X86_FADD, 1, 1); 1497 } 1498 1499 JIT_OP_FCOS, JIT_OP_DCOS, JIT_OP_NFCOS: stack 1500 [freg, scratch freg] -> { 1501 x86_fcos(inst); 1502 x86_fldz(inst); 1503 x86_fp_op_reg(inst, X86_FADD, 1, 1); 1504 } 1505 1506 JIT_OP_FSIN, JIT_OP_DSIN, JIT_OP_NFSIN: stack 1507 [freg, scratch freg] -> { 1508 x86_fsin(inst); 1509 x86_fldz(inst); 1510 x86_fp_op_reg(inst, X86_FADD, 1, 1); 1511 } 1512 1513 JIT_OP_FSQRT, JIT_OP_DSQRT, JIT_OP_NFSQRT: stack 1514 [freg] -> { 1515 x86_fsqrt(inst); 1516 } 1517 1518 /* 1519 * Absolute, minimum, maximum, and sign. 1520 */ 1521 1522 JIT_OP_IABS: 1523 [reg("eax"), scratch reg("edx")] -> { 1524 x86_cdq(inst); 1525 x86_alu_reg_reg(inst, X86_XOR, $1, $2); 1526 x86_alu_reg_reg(inst, X86_SUB, $1, $2); 1527 } 1528 1529 JIT_OP_LABS: 1530 [lreg, scratch reg] -> { 1531 x86_mov_reg_reg(inst, $2, %1, 4); 1532 x86_shift_reg_imm(inst, X86_SAR, $2, 31); 1533 x86_alu_reg_reg(inst, X86_XOR, $1, $2); 1534 x86_alu_reg_reg(inst, X86_XOR, %1, $2); 1535 x86_alu_reg_reg(inst, X86_SUB, $1, $2); 1536 x86_alu_reg_reg(inst, X86_SBB, %1, $2); 1537 } 1538 1539 JIT_OP_FABS, JIT_OP_DABS, JIT_OP_NFABS: stack 1540 [freg] -> { 1541 x86_fabs(inst); 1542 } 1543 1544 JIT_OP_IMIN_UN: 1545 [=+reg, +reg, reg] -> { 1546 x86_alu_reg_reg(inst, X86_SUB, $2, $3); 1547 x86_alu_reg_reg(inst, X86_SBB, $1, $1); 1548 x86_alu_reg_reg(inst, X86_AND, $1, $2); 1549 x86_alu_reg_reg(inst, X86_ADD, $1, $3); 1550 } 1551 1552 JIT_OP_ISIGN: 1553 [=reg, imm] -> { 1554 if($2 < 0) 1555 { 1556 x86_mov_reg_imm(inst, $1, -1); 1557 } 1558 else if($2 > 0) 1559 { 1560 x86_mov_reg_imm(inst, $1, 1); 1561 } 1562 else 1563 { 1564 x86_clear_reg(inst, $1); 1565 } 1566 } 1567 [=+reg, +reg] -> { 1568 x86_clear_reg(inst, $1); 1569 x86_test_reg_reg(inst, $2, $2); 1570 x86_set_reg(inst, X86_CC_NZ, $1, 0); 1571 x86_shift_reg_imm(inst, X86_SAR, $2, 31); 1572 x86_alu_reg_reg(inst, X86_OR, $1, $2); 1573 } 1574 1575 JIT_OP_LSIGN: 1576 [=reg, imm] -> { 1577 jit_long value = *((jit_long *)($2)); 1578 if(value < 0) 1579 { 1580 x86_mov_reg_imm(inst, $1, -1); 1581 } 1582 else if(value > 0) 1583 { 1584 x86_mov_reg_imm(inst, $1, 1); 1585 } 1586 else 1587 { 1588 x86_clear_reg(inst, $1); 1589 } 1590 } 1591 [=+reg, +lreg] -> { 1592 x86_clear_reg(inst, $1); 1593 x86_alu_reg_reg(inst, X86_OR, $2, %2); 1594 x86_set_reg(inst, X86_CC_NZ, $1, 0); 1595 x86_shift_reg_imm(inst, X86_SAR, %2, 31); 1596 x86_alu_reg_reg(inst, X86_OR, $1, %2); 1597 } 1598 1599 /* 1600 * Pointer check opcodes. 1601 */ 1602 1603 JIT_OP_CHECK_NULL: note 1604 [reg] -> { 1605 #if 0 && defined(JIT_USE_SIGNALS) 1606 /* if $1 contains NULL this generates SEGV and the signal 1607 handler will throw the exception */ 1608 x86_alu_reg_membase(inst, X86_CMP, $1, $1, 0); 1609 #else 1610 unsigned char *patch; 1611 x86_alu_reg_reg(inst, X86_OR, $1, $1); 1612 patch = inst; 1613 x86_branch8(inst, X86_CC_NE, 0, 0); 1614 inst = throw_builtin(inst, func, JIT_RESULT_NULL_REFERENCE); 1615 x86_patch(patch, inst); 1616 #endif 1617 } 1618 1619 /* 1620 * Function calls. 1621 */ 1622 1623 JIT_OP_CALL: 1624 [] -> { 1625 jit_function_t func = (jit_function_t)(insn->dest); 1626 x86_call_code(inst, jit_function_to_closure(func)); 1627 } 1628 1629 JIT_OP_CALL_TAIL: 1630 [] -> { 1631 jit_function_t func = (jit_function_t)(insn->dest); 1632 x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); 1633 x86_pop_reg(inst, X86_EBP); 1634 x86_jump_code(inst, jit_function_to_closure(func)); 1635 } 1636 1637 JIT_OP_CALL_INDIRECT: 1638 [] -> { 1639 x86_call_reg(inst, X86_EAX); 1640 } 1641 1642 JIT_OP_CALL_INDIRECT_TAIL: 1643 [] -> { 1644 x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); 1645 x86_pop_reg(inst, X86_EBP); 1646 x86_jump_reg(inst, X86_EAX); 1647 } 1648 1649 JIT_OP_CALL_VTABLE_PTR: 1650 [] -> { 1651 x86_call_reg(inst, X86_EAX); 1652 } 1653 1654 JIT_OP_CALL_VTABLE_PTR_TAIL: 1655 [] -> { 1656 x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); 1657 x86_pop_reg(inst, X86_EBP); 1658 x86_jump_reg(inst, X86_EAX); 1659 } 1660 1661 JIT_OP_CALL_EXTERNAL: 1662 [] -> { 1663 x86_call_code(inst, (void *)(insn->dest)); 1664 } 1665 1666 JIT_OP_CALL_EXTERNAL_TAIL: 1667 [] -> { 1668 x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); 1669 x86_pop_reg(inst, X86_EBP); 1670 x86_jump_code(inst, (void *)(insn->dest)); 1671 } 1672 1673 JIT_OP_RETURN: 1674 [] -> { 1675 inst = jump_to_epilog(gen, inst, block); 1676 } 1677 1678 JIT_OP_RETURN_INT: note 1679 [reg("eax")] -> { 1680 inst = jump_to_epilog(gen, inst, block); 1681 } 1682 1683 JIT_OP_RETURN_LONG: note 1684 [lreg("eax":"edx")] -> { 1685 inst = jump_to_epilog(gen, inst, block); 1686 } 1687 1688 JIT_OP_RETURN_FLOAT32: note, stack 1689 [freg, clobber(freg)] -> { 1690 /* clobber(freg) frees all registers on the fp stack */ 1691 inst = jump_to_epilog(gen, inst, block); 1692 } 1693 1694 JIT_OP_RETURN_FLOAT64: note, stack 1695 [freg, clobber(freg)] -> { 1696 /* clobber(freg) frees all registers on the fp stack */ 1697 inst = jump_to_epilog(gen, inst, block); 1698 } 1699 1700 JIT_OP_RETURN_NFLOAT: note, stack 1701 [freg, clobber(freg)] -> { 1702 /* clobber(freg) frees all registers on the fp stack */ 1703 inst = jump_to_epilog(gen, inst, block); 1704 } 1705 1706 JIT_OP_RETURN_SMALL_STRUCT: note 1707 [reg, imm] -> { 1708 switch($2) 1709 { 1710 case 1: 1711 x86_widen_membase(inst, X86_EAX, $1, 0, 0, 0); 1712 break; 1713 1714 case 2: 1715 x86_widen_membase(inst, X86_EAX, $1, 0, 0, 1); 1716 break; 1717 1718 case 3: 1719 if(X86_EAX == $1) 1720 { 1721 x86_widen_membase(inst, X86_EDX, $1, 0, 0, 1); 1722 x86_widen_membase(inst, X86_EAX, $1, 2, 0, 0); 1723 } 1724 else 1725 { 1726 x86_widen_membase(inst, X86_EAX, $1, 2, 0, 0); 1727 x86_widen_membase(inst, X86_EDX, $1, 0, 0, 1); 1728 } 1729 x86_shift_reg_imm(inst, X86_SHL, X86_EAX, 16); 1730 x86_alu_reg_reg(inst, X86_OR, X86_EAX, X86_EDX); 1731 break; 1732 1733 case 4: 1734 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1735 break; 1736 1737 case 5: 1738 if(X86_EAX == $1) 1739 { 1740 x86_widen_membase(inst, X86_EDX, $1, 4, 0, 0); 1741 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1742 } 1743 else 1744 { 1745 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1746 x86_widen_membase(inst, X86_EDX, $1, 4, 0, 0); 1747 } 1748 break; 1749 1750 case 6: 1751 if(X86_EAX == $1) 1752 { 1753 x86_widen_membase(inst, X86_EDX, $1, 4, 0, 1); 1754 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1755 } 1756 else 1757 { 1758 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1759 x86_widen_membase(inst, X86_EDX, $1, 4, 0, 1); 1760 } 1761 break; 1762 1763 case 7: 1764 if(X86_EAX == $1) 1765 { 1766 x86_widen_membase(inst, X86_ECX, $1, 4, 0, 1); 1767 x86_widen_membase(inst, X86_EDX, $1, 6, 0, 0); 1768 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1769 } 1770 else if(X86_ECX == $1) 1771 { 1772 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1773 x86_widen_membase(inst, X86_EDX, $1, 6, 0, 0); 1774 x86_widen_membase(inst, X86_ECX, $1, 4, 0, 1); 1775 } 1776 else 1777 { 1778 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1779 x86_widen_membase(inst, X86_ECX, $1, 4, 0, 1); 1780 x86_widen_membase(inst, X86_EDX, $1, 6, 0, 0); 1781 } 1782 x86_shift_reg_imm(inst, X86_SHL, X86_EDX, 16); 1783 x86_alu_reg_reg(inst, X86_OR, X86_EDX, X86_ECX); 1784 break; 1785 1786 case 8: 1787 if(X86_EAX == $1) 1788 { 1789 x86_mov_reg_membase(inst, X86_EDX, $1, 4, 4); 1790 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1791 } 1792 else 1793 { 1794 x86_mov_reg_membase(inst, X86_EAX, $1, 0, 4); 1795 x86_mov_reg_membase(inst, X86_EDX, $1, 4, 4); 1796 } 1797 break; 1798 } 1799 1800 inst = jump_to_epilog(gen, inst, block); 1801 } 1802 1803 /* 1804 * Exception handling. 1805 */ 1806 1807 JIT_OP_THROW: branch 1808 [reg] -> { 1809 x86_push_reg(inst, $1); 1810 if(func->builder->setjmp_value != 0) 1811 { 1812 /* We have a "setjmp" block in the current function, 1813 so we must record the location of the throw first */ 1814 _jit_gen_fix_value(func->builder->setjmp_value); 1815 if(func->builder->position_independent) 1816 { 1817 x86_call_imm(inst, 0); 1818 x86_pop_membase(inst, X86_EBP, 1819 func->builder->setjmp_value->frame_offset 1820 + jit_jmp_catch_pc_offset); 1821 } 1822 else 1823 { 1824 int pc = (int) inst; 1825 x86_mov_membase_imm(inst, X86_EBP, 1826 func->builder->setjmp_value->frame_offset 1827 + jit_jmp_catch_pc_offset, pc, 4); 1828 } 1829 } 1830 x86_call_code(inst, (void *)jit_exception_throw); 1831 } 1832 1833 JIT_OP_RETHROW: manual 1834 [] -> { /* Not used in native code back ends */ } 1835 1836 JIT_OP_LOAD_PC: 1837 [=reg] -> { 1838 if(func->builder->position_independent) 1839 { 1840 x86_call_imm(inst, 0); 1841 x86_pop_reg(inst, $1); 1842 } 1843 else 1844 { 1845 int pc = (int) inst; 1846 x86_mov_reg_imm(inst, $1, pc); 1847 } 1848 } 1849 1850 JIT_OP_LOAD_EXCEPTION_PC: manual 1851 [] -> { /* Not used in native code back ends */ } 1852 1853 JIT_OP_ENTER_FINALLY: manual 1854 [] -> { /* Nothing to do here: return address on the stack */ } 1855 1856 JIT_OP_LEAVE_FINALLY: branch 1857 [] -> { 1858 /* The "finally" return address is on the stack */ 1859 x86_ret(inst); 1860 } 1861 1862 JIT_OP_CALL_FINALLY: branch 1863 [] -> { 1864 jit_block_t block; 1865 1866 block = jit_block_from_label(func, (jit_label_t)(insn->dest)); 1867 if(!block) 1868 { 1869 return; 1870 } 1871 1872 if(block->address) 1873 { 1874 x86_call_code(inst, block->address); 1875 } 1876 else 1877 { 1878 x86_call_imm(inst, block->fixup_list); 1879 block->fixup_list = (void *)(inst - 4); 1880 } 1881 } 1882 1883 JIT_OP_ENTER_FILTER: manual 1884 [] -> { 1885 /* TODO */ 1886 TODO(); 1887 } 1888 1889 JIT_OP_LEAVE_FILTER: manual 1890 [] -> { 1891 /* TODO */ 1892 TODO(); 1893 } 1894 1895 JIT_OP_CALL_FILTER: manual 1896 [] -> { 1897 /* TODO */ 1898 TODO(); 1899 } 1900 1901 JIT_OP_CALL_FILTER_RETURN: manual 1902 [] -> { 1903 /* TODO */ 1904 TODO(); 1905 } 1906 1907 JIT_OP_ADDRESS_OF_LABEL: 1908 [=reg] -> { 1909 block = jit_block_from_label(func, (jit_label_t)(insn->value1)); 1910 if(func->builder->position_independent) 1911 { 1912 /* TODO */ 1913 TODO(); 1914 } 1915 else 1916 { 1917 if(block->address) 1918 { 1919 x86_mov_reg_imm(inst, $1, block->address); 1920 } 1921 else 1922 { 1923 /* Output a placeholder and record on the block's fixup list */ 1924 x86_mov_reg_imm(inst, $1, (int)(block->fixup_absolute_list)); 1925 block->fixup_absolute_list = (void *)(inst - 4); 1926 } 1927 } 1928 } 1929 1930 /* 1931 * Data manipulation. 1932 */ 1933 1934 JIT_OP_COPY_LOAD_SBYTE, JIT_OP_COPY_LOAD_UBYTE, JIT_OP_COPY_STORE_BYTE: copy 1935 [=local, imm] -> { 1936 x86_mov_membase_imm(inst, X86_EBP, $1, $2, 1); 1937 } 1938 [=local, breg] -> { 1939 x86_mov_membase_reg(inst, X86_EBP, $1, $2, 1); 1940 } 1941 [reg] -> {} 1942 1943 JIT_OP_COPY_LOAD_SHORT, JIT_OP_COPY_LOAD_USHORT, JIT_OP_COPY_STORE_SHORT: copy 1944 [=local, imm] -> { 1945 x86_mov_membase_imm(inst, X86_EBP, $1, $2, 2); 1946 } 1947 [=local, reg] -> { 1948 x86_mov_membase_reg(inst, X86_EBP, $1, $2, 2); 1949 } 1950 [reg] -> {} 1951 1952 JIT_OP_COPY_INT: copy 1953 [=local, imm] -> { 1954 x86_mov_membase_imm(inst, X86_EBP, $1, $2, 4); 1955 } 1956 [reg] -> {} 1957 1958 JIT_OP_COPY_LONG: copy 1959 [lreg] -> {} 1960 1961 JIT_OP_COPY_FLOAT32: copy, stack 1962 [freg] -> {} 1963 1964 JIT_OP_COPY_FLOAT64: copy, stack 1965 [freg] -> {} 1966 1967 JIT_OP_COPY_NFLOAT: copy, stack 1968 [freg] -> {} 1969 1970 JIT_OP_COPY_STRUCT: 1971 [=frame, frame, clobber(reg)] -> { 1972 inst = memory_copy(gen, inst, X86_EBP, $1, X86_EBP, $2, 1973 jit_type_get_size(jit_value_get_type(insn->dest))); 1974 } 1975 1976 JIT_OP_ADDRESS_OF: 1977 [=reg, frame] -> { 1978 x86_lea_membase(inst, $1, X86_EBP, $2); 1979 } 1980 1981 /* 1982 * Stack pushes and pops. 1983 */ 1984 1985 JIT_OP_INCOMING_REG, JIT_OP_RETURN_REG: note 1986 [reg] -> { 1987 /* 1988 * This rule does nothing itself. Also at this point 1989 * the value is supposed to be already in the register 1990 * so the "reg" pattern does not load it either. But 1991 * it allows the allocator to check the liveness flags 1992 * and free the register if the value is dead. 1993 */ 1994 } 1995 1996 JIT_OP_RETRIEVE_FRAME_POINTER: note 1997 [=reg] -> { 1998 x86_mov_reg_reg(inst, $1, X86_EBP, 4); 1999 } 2000 2001 JIT_OP_PUSH_INT: note 2002 [imm] -> { 2003 x86_push_imm(inst, $1); 2004 gen->stack_changed = 1; 2005 } 2006 [local] -> { 2007 x86_push_membase(inst, X86_EBP, $1); 2008 gen->stack_changed = 1; 2009 } 2010 [reg] -> { 2011 x86_push_reg(inst, $1); 2012 gen->stack_changed = 1; 2013 } 2014 2015 JIT_OP_PUSH_LONG: note 2016 [imm] -> { 2017 x86_push_imm(inst, ((jit_int *)($1))[1]); 2018 x86_push_imm(inst, ((jit_int *)($1))[0]); 2019 gen->stack_changed = 1; 2020 } 2021 [local] -> { 2022 x86_push_membase(inst, X86_EBP, $1 + 4); 2023 x86_push_membase(inst, X86_EBP, $1); 2024 gen->stack_changed = 1; 2025 } 2026 [lreg] -> { 2027 x86_push_reg(inst, %1); 2028 x86_push_reg(inst, $1); 2029 gen->stack_changed = 1; 2030 } 2031 2032 JIT_OP_PUSH_FLOAT32: note, stack 2033 [imm] -> { 2034 jit_int *ptr = (jit_int *)($1); 2035 x86_push_imm(inst, ptr[0]); 2036 gen->stack_changed = 1; 2037 } 2038 [local] -> { 2039 x86_push_membase(inst, X86_EBP, $1); 2040 gen->stack_changed = 1; 2041 } 2042 [freg] -> { 2043 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float32)); 2044 x86_fst_membase(inst, X86_ESP, 0, 0, 1); 2045 gen->stack_changed = 1; 2046 } 2047 2048 JIT_OP_PUSH_FLOAT64: note, stack 2049 [imm] -> { 2050 jit_int *ptr = (jit_int *)($1); 2051 x86_push_imm(inst, ptr[1]); 2052 x86_push_imm(inst, ptr[0]); 2053 gen->stack_changed = 1; 2054 } 2055 [local] -> { 2056 x86_push_membase(inst, X86_EBP, $1 + 4); 2057 x86_push_membase(inst, X86_EBP, $1); 2058 gen->stack_changed = 1; 2059 } 2060 [freg] -> { 2061 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64)); 2062 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 2063 gen->stack_changed = 1; 2064 } 2065 2066 JIT_OP_PUSH_NFLOAT: note, stack 2067 [imm] -> { 2068 jit_int *ptr = (jit_int *)($1); 2069 if(sizeof(jit_nfloat) != sizeof(jit_float64)) 2070 { 2071 x86_push_imm(inst, ptr[2]); 2072 } 2073 x86_push_imm(inst, ptr[1]); 2074 x86_push_imm(inst, ptr[0]); 2075 gen->stack_changed = 1; 2076 } 2077 [local] -> { 2078 if(sizeof(jit_nfloat) != sizeof(jit_float64)) 2079 { 2080 x86_push_membase(inst, X86_EBP, $1 + 8); 2081 } 2082 x86_push_membase(inst, X86_EBP, $1 + 4); 2083 x86_push_membase(inst, X86_EBP, $1); 2084 gen->stack_changed = 1; 2085 } 2086 [freg] -> { 2087 if(sizeof(jit_nfloat) != sizeof(jit_float64)) 2088 { 2089 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_nfloat)); 2090 x86_fst80_membase(inst, X86_ESP, 0); 2091 } 2092 else 2093 { 2094 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64)); 2095 x86_fst_membase(inst, X86_ESP, 0, 1, 1); 2096 } 2097 gen->stack_changed = 1; 2098 } 2099 2100 JIT_OP_PUSH_STRUCT: note, more_space 2101 [reg, clobber(reg)] -> { 2102 jit_nuint size; 2103 size = (jit_nuint)jit_value_get_nint_constant(insn->value2); 2104 if((size % sizeof(void *)) == 0 && size <= 4 * sizeof(void *)) 2105 { 2106 /* Handle small structures that are a multiple of the word size */ 2107 while(size > 0) 2108 { 2109 size -= sizeof(void *); 2110 x86_push_membase(inst, $1, size); 2111 } 2112 } 2113 else 2114 { 2115 /* Handle arbitrary-sized structures */ 2116 x86_alu_reg_imm(inst, X86_SUB, X86_ESP, ROUND_STACK(size)); 2117 inst = memory_copy(gen, inst, X86_ESP, 0, $1, 0, size); 2118 } 2119 gen->stack_changed = 1; 2120 } 2121 2122 JIT_OP_POP_STACK: 2123 [] -> { 2124 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, insn->value1->address); 2125 gen->stack_changed = 1; 2126 } 2127 2128 JIT_OP_FLUSH_SMALL_STRUCT: 2129 [] -> { 2130 jit_nuint size; 2131 jit_nint offset; 2132 _jit_gen_fix_value(insn->value1); 2133 size = jit_type_get_size(jit_value_get_type(insn->value1)); 2134 offset = insn->value1->frame_offset; 2135 inst = store_small_struct 2136 (inst, X86_EAX, X86_EDX, X86_EBP, offset, (jit_nint)size, 0); 2137 } 2138 2139 /* 2140 * Pointer-relative loads and stores. 2141 */ 2142 2143 JIT_OP_LOAD_RELATIVE_SBYTE: 2144 [=reg, reg, imm] -> { 2145 x86_widen_membase(inst, $1, $2, $3, 1, 0); 2146 } 2147 2148 JIT_OP_LOAD_RELATIVE_UBYTE: 2149 [=reg, reg, imm] -> { 2150 x86_widen_membase(inst, $1, $2, $3, 0, 0); 2151 } 2152 2153 JIT_OP_LOAD_RELATIVE_SHORT: 2154 [=reg, reg, imm] -> { 2155 x86_widen_membase(inst, $1, $2, $3, 1, 1); 2156 } 2157 2158 JIT_OP_LOAD_RELATIVE_USHORT: 2159 [=reg, reg, imm] -> { 2160 x86_widen_membase(inst, $1, $2, $3, 0, 1); 2161 } 2162 2163 JIT_OP_LOAD_RELATIVE_INT: 2164 [=reg, reg, imm] -> { 2165 x86_mov_reg_membase(inst, $1, $2, $3, 4); 2166 } 2167 2168 JIT_OP_LOAD_RELATIVE_LONG: 2169 [=lreg, reg, imm] -> { 2170 if($1 == $2) 2171 { 2172 x86_mov_reg_membase(inst, %1, $2, $3 + 4, 4); 2173 x86_mov_reg_membase(inst, $1, $2, $3, 4); 2174 } 2175 else 2176 { 2177 x86_mov_reg_membase(inst, $1, $2, $3, 4); 2178 x86_mov_reg_membase(inst, %1, $2, $3 + 4, 4); 2179 } 2180 } 2181 2182 JIT_OP_LOAD_RELATIVE_FLOAT32: 2183 [=freg, reg, imm] -> { 2184 x86_fld_membase(inst, $2, $3, 0); 2185 } 2186 2187 JIT_OP_LOAD_RELATIVE_FLOAT64: 2188 [=freg, reg, imm] -> { 2189 x86_fld_membase(inst, $2, $3, 1); 2190 } 2191 2192 JIT_OP_LOAD_RELATIVE_NFLOAT: 2193 [=freg, reg, imm, if("sizeof(jit_nfloat) != sizeof(jit_float64)")] -> { 2194 x86_fld80_membase(inst, $2, $3); 2195 } 2196 [=freg, reg, imm, if("sizeof(jit_nfloat) == sizeof(jit_float64)")] -> { 2197 x86_fld_membase(inst, $2, $3, 1); 2198 } 2199 2200 JIT_OP_LOAD_RELATIVE_STRUCT: more_space 2201 [=frame, reg, imm, clobber(reg)] -> { 2202 inst = memory_copy(gen, inst, X86_EBP, $1, $2, $3, 2203 jit_type_get_size(jit_value_get_type(insn->dest))); 2204 } 2205 2206 JIT_OP_STORE_RELATIVE_BYTE: ternary 2207 [imm, imm, imm] -> { 2208 x86_mov_mem_imm(inst, $1 + $3, $2, 1); 2209 } 2210 [imm, breg, imm] -> { 2211 x86_mov_mem_reg(inst, $1 + $3, $2, 1); 2212 } 2213 [reg, imm, imm] -> { 2214 x86_mov_membase_imm(inst, $1, $3, $2, 1); 2215 } 2216 [reg, breg, imm] -> { 2217 x86_mov_membase_reg(inst, $1, $3, $2, 1); 2218 } 2219 2220 JIT_OP_STORE_RELATIVE_SHORT: ternary 2221 [imm, imm, imm] -> { 2222 x86_mov_mem_imm(inst, $1 + $3, $2, 2); 2223 } 2224 [imm, reg, imm] -> { 2225 x86_mov_mem_reg(inst, $1 + $3, $2, 2); 2226 } 2227 [reg, imm, imm] -> { 2228 x86_mov_membase_imm(inst, $1, $3, $2, 2); 2229 } 2230 [reg, reg, imm] -> { 2231 x86_mov_membase_reg(inst, $1, $3, $2, 2); 2232 } 2233 2234 JIT_OP_STORE_RELATIVE_INT: ternary 2235 [imm, imm, imm] -> { 2236 x86_mov_mem_imm(inst, $1 + $3, $2, 4); 2237 } 2238 [imm, reg, imm] -> { 2239 x86_mov_mem_reg(inst, $1 + $3, $2, 4); 2240 } 2241 [reg, imm, imm] -> { 2242 x86_mov_membase_imm(inst, $1, $3, $2, 4); 2243 } 2244 [reg, reg, imm] -> { 2245 x86_mov_membase_reg(inst, $1, $3, $2, 4); 2246 } 2247 2248 JIT_OP_STORE_RELATIVE_LONG: ternary 2249 [reg, imm, imm] -> { 2250 x86_mov_membase_imm(inst, $1, $3, *(int *)($2), 4); 2251 x86_mov_membase_imm(inst, $1, $3 + 4, *(int *)($2 + 4), 4); 2252 } 2253 [reg, local, imm, scratch reg] -> { 2254 x86_mov_reg_membase(inst, $4, X86_EBP, $2, 4); 2255 x86_mov_membase_reg(inst, $1, $3, $4, 4); 2256 x86_mov_reg_membase(inst, $4, X86_EBP, $2 + 4, 4); 2257 x86_mov_membase_reg(inst, $1, $3 + 4, $4, 4); 2258 } 2259 [reg, lreg, imm] -> { 2260 x86_mov_membase_reg(inst, $1, $3, $2, 4); 2261 x86_mov_membase_reg(inst, $1, $3 + 4, %2, 4); 2262 } 2263 2264 JIT_OP_STORE_RELATIVE_FLOAT32: ternary, stack 2265 [reg, imm, imm] -> { 2266 x86_mov_membase_imm(inst, $1, $3, ((int *)($2))[0], 4); 2267 } 2268 [reg, freg, imm] -> { 2269 x86_fst_membase(inst, $1, $3, 0, 1); 2270 } 2271 2272 JIT_OP_STORE_RELATIVE_FLOAT64: ternary, stack 2273 [reg, imm, imm] -> { 2274 x86_mov_membase_imm(inst, $1, $3, ((int *)($2))[0], 4); 2275 x86_mov_membase_imm(inst, $1, $3 + 4, ((int *)($2))[1], 4); 2276 } 2277 [reg, freg, imm] -> { 2278 x86_fst_membase(inst, $1, $3, 1, 1); 2279 } 2280 2281 JIT_OP_STORE_RELATIVE_NFLOAT: ternary, stack 2282 [reg, imm, imm] -> { 2283 x86_mov_membase_imm(inst, $1, $3, ((int *)($2))[0], 4); 2284 x86_mov_membase_imm(inst, $1, $3 + 4, ((int *)($2))[1], 4); 2285 if(sizeof(jit_nfloat) != sizeof(jit_float64)) 2286 { 2287 x86_mov_membase_imm(inst, $1, $3 + 8, ((int *)($2))[2], 4); 2288 } 2289 } 2290 [reg, freg, imm] -> { 2291 if(sizeof(jit_nfloat) != sizeof(jit_float64)) 2292 { 2293 x86_fst80_membase(inst, $1, $3); 2294 } 2295 else 2296 { 2297 x86_fst_membase(inst, $1, $3, 1, 1); 2298 } 2299 } 2300 2301 JIT_OP_STORE_RELATIVE_STRUCT: manual 2302 [] -> { 2303 unsigned char *inst; 2304 int reg = _jit_regs_load_value 2305 (gen, insn->dest, 0, 2306 (insn->flags & (JIT_INSN_DEST_NEXT_USE | 2307 JIT_INSN_DEST_LIVE))); 2308 _jit_regs_spill_all(gen); 2309 _jit_gen_fix_value(insn->value1); 2310 inst = gen->ptr; 2311 _jit_gen_check_space(gen, 128); 2312 reg = _jit_reg_info[reg].cpu_reg; 2313 inst = memory_copy(gen, inst, reg, (int)(insn->value2->address), 2314 X86_EBP, insn->value1->frame_offset, 2315 jit_type_get_size(jit_value_get_type(insn->value1))); 2316 gen->ptr = inst; 2317 } 2318 2319 JIT_OP_ADD_RELATIVE: 2320 [reg, imm] -> { 2321 if(insn->value2->address != 0) 2322 { 2323 x86_alu_reg_imm(inst, X86_ADD, $1, $2); 2324 } 2325 } 2326 2327 /* 2328 * Array element loads and stores. 2329 */ 2330 2331 JIT_OP_LOAD_ELEMENT_SBYTE: 2332 [=reg, reg, reg] -> { 2333 x86_widen_memindex(inst, $1, $2, 0, $3, 0, 1, 0); 2334 } 2335 2336 JIT_OP_LOAD_ELEMENT_UBYTE: 2337 [=reg, reg, reg] -> { 2338 x86_widen_memindex(inst, $1, $2, 0, $3, 0, 0, 0); 2339 } 2340 2341 JIT_OP_LOAD_ELEMENT_SHORT: 2342 [=reg, reg, reg] -> { 2343 x86_widen_memindex(inst, $1, $2, 0, $3, 1, 1, 1); 2344 } 2345 2346 JIT_OP_LOAD_ELEMENT_USHORT: 2347 [=reg, reg, reg] -> { 2348 x86_widen_memindex(inst, $1, $2, 0, $3, 1, 0, 1); 2349 } 2350 2351 JIT_OP_LOAD_ELEMENT_INT: 2352 [=reg, reg, reg] -> { 2353 x86_mov_reg_memindex(inst, $1, $2, 0, $3, 2, 4); 2354 } 2355 2356 JIT_OP_LOAD_ELEMENT_LONG: 2357 [=lreg, reg, reg] -> { 2358 if($1 == $2 || $1 == $3) 2359 { 2360 x86_mov_reg_memindex(inst, %1, $2, 4, $3, 3, 4); 2361 x86_mov_reg_memindex(inst, $1, $2, 0, $3, 3, 4); 2362 } 2363 else 2364 { 2365 x86_mov_reg_memindex(inst, $1, $2, 0, $3, 3, 4); 2366 x86_mov_reg_memindex(inst, %1, $2, 4, $3, 3, 4); 2367 } 2368 } 2369 2370 JIT_OP_LOAD_ELEMENT_FLOAT32: 2371 [=freg, reg, reg] -> { 2372 x86_fld_memindex(inst, $2, 0, $3, 2, 0); 2373 } 2374 2375 JIT_OP_LOAD_ELEMENT_FLOAT64: 2376 [=freg, reg, reg] -> { 2377 x86_fld_memindex(inst, $2, 0, $3, 3, 1); 2378 } 2379 2380 JIT_OP_LOAD_ELEMENT_NFLOAT: 2381 [=freg, reg, +reg, if("sizeof(jit_nfloat) != sizeof(jit_float64)")] -> { 2382 /* lea $3, [$3 + $3 * 2] */ 2383 x86_lea_memindex(inst, $3, $3, 0, $3, 1); 2384 /* fld [$2 * 4] */ 2385 x86_fld80_memindex(inst, $2, 0, $3, 2); 2386 } 2387 [=freg, reg, reg, if("sizeof(jit_nfloat) == sizeof(jit_float64)")] -> { 2388 x86_fld_memindex(inst, $2, 0, $3, 3, 1); 2389 } 2390 2391 JIT_OP_STORE_ELEMENT_BYTE: ternary 2392 [reg, reg, breg] -> { 2393 x86_mov_memindex_reg(inst, $1, 0, $2, 0, $3, 1); 2394 } 2395 2396 JIT_OP_STORE_ELEMENT_SHORT: ternary 2397 [reg, reg, reg] -> { 2398 x86_mov_memindex_reg(inst, $1, 0, $2, 1, $3, 2); 2399 } 2400 2401 JIT_OP_STORE_ELEMENT_INT: ternary 2402 [reg, reg, reg] -> { 2403 x86_mov_memindex_reg(inst, $1, 0, $2, 2, $3, 4); 2404 } 2405 2406 JIT_OP_STORE_ELEMENT_LONG: ternary 2407 [reg, reg, imm] -> { 2408 x86_mov_memindex_imm(inst, $1, 0, $2, 3, *(int *)($3), 4); 2409 x86_mov_memindex_imm(inst, $1, 4, $2, 3, *(int *)($3 + 4), 4); 2410 } 2411 [reg, reg, local, scratch reg] -> { 2412 x86_mov_reg_membase(inst, $4, X86_EBP, $3, 4); 2413 x86_mov_memindex_reg(inst, $1, 0, $2, 3, $4, 4); 2414 x86_mov_reg_membase(inst, $4, X86_EBP, $3 + 4, 4); 2415 x86_mov_memindex_reg(inst, $1, 4, $2, 3, $4, 4); 2416 } 2417 [reg, reg, lreg] -> { 2418 x86_mov_memindex_reg(inst, $1, 0, $2, 3, $3, 4); 2419 x86_mov_memindex_reg(inst, $1, 4, $2, 3, %3, 4); 2420 } 2421 2422 JIT_OP_STORE_ELEMENT_FLOAT32: ternary, stack 2423 [reg, reg, freg] -> { 2424 x86_fst_memindex(inst, $1, 0, $2, 2, 0, 1); 2425 } 2426 2427 JIT_OP_STORE_ELEMENT_FLOAT64: ternary, stack 2428 [reg, reg, freg] -> { 2429 x86_fst_memindex(inst, $1, 0, $2, 3, 1, 1); 2430 } 2431 2432 JIT_OP_STORE_ELEMENT_NFLOAT: ternary, stack 2433 [reg, +reg, freg, if("sizeof(jit_nfloat) != sizeof(jit_float64)")] -> { 2434 /* lea reg2, [reg2 + reg2 * 2] */ 2435 x86_lea_memindex(inst, $2, $2, 0, $2, 1); 2436 /* fst [reg2 * 4] */ 2437 x86_fst80_memindex(inst, $1, 0, $2, 2); 2438 } 2439 [reg, reg, freg, if("sizeof(jit_nfloat) == sizeof(jit_float64)")] -> { 2440 x86_fst_memindex(inst, $1, 0, $2, 3, 1, 1); 2441 } 2442 2443 /* 2444 * Block operations. 2445 */ 2446 2447 JIT_OP_MEMCPY: ternary 2448 [any, any, imm, if("$3 <= 0")] -> { } 2449 [reg, reg, imm, scratch breg, if("$3 <= 32"), space("32 + $3 * 4")] -> { 2450 int disp; 2451 disp = 0; 2452 while($3 >= (disp + 4)) 2453 { 2454 x86_mov_reg_membase(inst, $4, $2, disp, 4); 2455 x86_mov_membase_reg(inst, $1, disp, $4, 4); 2456 disp += 4; 2457 } 2458 if($3 >= (disp + 2)) 2459 { 2460 x86_mov_reg_membase(inst, $4, $2, disp, 2); 2461 x86_mov_membase_reg(inst, $1, disp, $4, 2); 2462 disp += 2; 2463 } 2464 if($3 > disp) 2465 { 2466 x86_mov_reg_membase(inst, $4, $2, disp, 1); 2467 x86_mov_membase_reg(inst, $1, disp, $4, 1); 2468 } 2469 } 2470 [reg, reg, reg, clobber("eax", "ecx", "edx", "ebx")] -> { 2471 x86_push_reg(inst, $3); 2472 x86_push_reg(inst, $2); 2473 x86_push_reg(inst, $1); 2474 x86_call_code(inst, jit_memcpy); 2475 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 3 * sizeof(void *)); 2476 } 2477 2478 JIT_OP_MEMMOVE: ternary 2479 [any, any, imm, if("$3 <= 0")] -> { } 2480 [reg, reg, reg, clobber("eax", "ecx", "edx", "ebx")] -> { 2481 x86_push_reg(inst, $3); 2482 x86_push_reg(inst, $2); 2483 x86_push_reg(inst, $1); 2484 x86_call_code(inst, jit_memmove); 2485 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 3 * sizeof(void *)); 2486 } 2487 2488 JIT_OP_MEMSET: ternary 2489 [any, any, imm, if("$3 <= 0")] -> { } 2490 [reg, imm, imm, if("$3 <= 32"), space("32 + $3 * 4")] -> { 2491 int disp; 2492 disp = 0; 2493 while($3 >= (disp + 4)) 2494 { 2495 x86_mov_membase_imm(inst, $1, disp, $2 * 0x01010101, 4); 2496 disp += 4; 2497 } 2498 if($3 >= (disp + 2)) 2499 { 2500 x86_mov_membase_imm(inst, $1, disp, $2 * 0x0101, 2); 2501 disp += 2; 2502 } 2503 if(insn->value2->address > disp) 2504 { 2505 x86_mov_membase_imm(inst, $1, disp, $2, 1); 2506 } 2507 } 2508 [reg, breg, imm, if("$3 < 4")] -> { 2509 x86_mov_membase_reg(inst, $1, 0, $2, 1); 2510 if($3 > 1) 2511 { 2512 x86_mov_membase_reg(inst, $1, 1, $2, 1); 2513 if($3 > 2) 2514 { 2515 x86_mov_membase_reg(inst, $1, 2, $2, 1); 2516 } 2517 } 2518 } 2519 [reg, +reg, imm, scratch reg, 2520 if("$3 <= 32 && ($3 % 2) == 0"), space("32 + $3 * 4")] -> { 2521 int disp; 2522 x86_mov_reg_reg(inst, $4, $2, 4); 2523 x86_shift_reg_imm(inst, X86_SHL, $2, 8); 2524 x86_alu_reg_reg(inst, X86_OR, $2, $4); 2525 x86_mov_reg_reg(inst, $4, $2, 4); 2526 x86_shift_reg_imm(inst, X86_SHL, $2, 16); 2527 x86_alu_reg_reg(inst, X86_OR, $2, $4); 2528 disp = 0; 2529 while($3 >= (disp + 4)) 2530 { 2531 x86_mov_membase_reg(inst, $1, disp, $2, 4); 2532 disp += 4; 2533 } 2534 if($3 > disp) 2535 { 2536 x86_mov_membase_reg(inst, $1, disp, $2, 2); 2537 } 2538 } 2539 [reg, +breg, imm, scratch reg, 2540 if("$3 <= 32 && ($3 % 2) != 0"), space("32 + $3 * 4")] -> { 2541 int disp; 2542 x86_mov_reg_reg(inst, $4, $2, 4); 2543 x86_shift_reg_imm(inst, X86_SHL, $2, 8); 2544 x86_alu_reg_reg(inst, X86_OR, $2, $4); 2545 x86_mov_reg_reg(inst, $4, $2, 4); 2546 x86_shift_reg_imm(inst, X86_SHL, $2, 16); 2547 x86_alu_reg_reg(inst, X86_OR, $2, $4); 2548 disp = 0; 2549 while($3 >= (disp + 4)) 2550 { 2551 x86_mov_membase_reg(inst, $1, disp, $2, 4); 2552 disp += 4; 2553 } 2554 if($3 >= (disp + 2)) 2555 { 2556 x86_mov_membase_reg(inst, $1, disp, $2, 2); 2557 disp += 2; 2558 } 2559 if($3 > disp) 2560 { 2561 x86_mov_membase_reg(inst, $1, disp, $2, 1); 2562 } 2563 } 2564 [reg, reg, reg, clobber("eax", "ecx", "edx", "ebx")] -> { 2565 x86_push_reg(inst, $3); 2566 x86_push_reg(inst, $2); 2567 x86_push_reg(inst, $1); 2568 x86_call_code(inst, jit_memset); 2569 x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 3 * sizeof(void *)); 2570 } 2571 2572 /* 2573 * Allocate memory from the stack. 2574 */ 2575 2576 JIT_OP_ALLOCA: 2577 [reg] -> { 2578 x86_alu_reg_reg(inst, X86_SUB, X86_ESP, $1); 2579 x86_mov_reg_reg(inst, $1, X86_ESP, 4); 2580 gen->stack_changed = 1; 2581 } 2582 2583 JIT_OP_JUMP_TABLE: ternary, branch 2584 [reg, imm, imm, space("32 + sizeof(void *) * $3")] -> { 2585 unsigned char *patch_jump_table; 2586 unsigned char *patch_fall_through; 2587 int index; 2588 jit_label_t *labels; 2589 jit_nint num_labels; 2590 jit_block_t block; 2591 2592 labels = (jit_label_t *) $2; 2593 num_labels = $3; 2594 2595 x86_alu_reg_imm(inst, X86_CMP, $1, num_labels); 2596 patch_fall_through = inst; 2597 x86_branch32(inst, X86_CC_AE, 0, 0); 2598 2599 if(func->builder->position_independent) 2600 { 2601 /* TODO */ 2602 TODO(); 2603 } 2604 else 2605 { 2606 patch_jump_table = inst; 2607 x86_jump_memindex(inst, X86_NOBASEREG, 0, $1, 2); 2608 while(((jit_nint) inst & (sizeof(void*) - 1)) != 0) 2609 { 2610 x86_nop(inst); 2611 } 2612 2613 // displacement goes after opcode. ModR/M, and SIB bytes 2614 *((void **)(patch_jump_table + 3)) = inst; 2615 } 2616 2617 for(index = 0; index < num_labels; index++) 2618 { 2619 block = jit_block_from_label(func, labels[index]); 2620 if(!block) 2621 { 2622 return; 2623 } 2624 2625 if(func->builder->position_independent) 2626 { 2627 /* TODO */ 2628 TODO(); 2629 } 2630 else 2631 { 2632 if(block->address) 2633 { 2634 x86_imm_emit32(inst, block->address); 2635 } 2636 else 2637 { 2638 /* Output a placeholder and record on the block's fixup list */ 2639 x86_imm_emit32(inst, (int)(block->fixup_absolute_list)); 2640 block->fixup_absolute_list = (void *)(inst - 4); 2641 } 2642 } 2643 } 2644 2645 x86_patch(patch_fall_through, inst); 2646 }