/usr/include/js/NativeX64.h is in libmozjs185-dev 1.8.5-1.0.0+dfsg-4.5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is [Open Source Virtual Machine].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __nanojit_NativeX64__
#define __nanojit_NativeX64__
#include "NativeCommon.h"
#ifndef NANOJIT_64BIT
#error "NANOJIT_64BIT must be defined for X64 backend"
#endif
#ifdef PERFM
#define DOPROF
#include "../vprof/vprof.h"
#define count_instr() _nvprof("x64",1)
#define count_prolog() _nvprof("x64-prolog",1); count_instr();
#define count_imt() _nvprof("x64-imt",1) count_instr()
#else
#define count_instr()
#define count_prolog()
#define count_imt()
#endif
namespace nanojit
{
#define NJ_MAX_STACK_ENTRY 4096
#define NJ_ALIGN_STACK 16
#define NJ_JTBL_SUPPORTED 1
#define NJ_EXPANDED_LOADSTORE_SUPPORTED 1
#define NJ_F2I_SUPPORTED 1
#define NJ_SOFTFLOAT_SUPPORTED 0
#define NJ_DIVI_SUPPORTED 1
static const Register RAX = { 0 }; // 1st int return, # of sse varargs
static const Register RCX = { 1 }; // 4th int arg
static const Register RDX = { 2 }; // 3rd int arg 2nd return
static const Register RBX = { 3 }; // saved
static const Register RSP = { 4 }; // stack ptr
static const Register RBP = { 5 }; // frame ptr, saved, sib reqd
static const Register RSI = { 6 }; // 2nd int arg
static const Register RDI = { 7 }; // 1st int arg
static const Register R8 = { 8 }; // 5th int arg
static const Register R9 = { 9 }; // 6th int arg
static const Register R10 = { 10 }; // scratch
static const Register R11 = { 11 }; // scratch
static const Register R12 = { 12 }; // saved
static const Register R13 = { 13 }; // saved, sib reqd like rbp
static const Register R14 = { 14 }; // saved
static const Register R15 = { 15 }; // saved
static const Register XMM0 = { 16 }; // 1st double arg, return
static const Register XMM1 = { 17 }; // 2nd double arg, return
static const Register XMM2 = { 18 }; // 3rd double arg
static const Register XMM3 = { 19 }; // 4th double arg
static const Register XMM4 = { 20 }; // 5th double arg
static const Register XMM5 = { 21 }; // 6th double arg
static const Register XMM6 = { 22 }; // 7th double arg
static const Register XMM7 = { 23 }; // 8th double arg
static const Register XMM8 = { 24 }; // scratch
static const Register XMM9 = { 25 }; // scratch
static const Register XMM10 = { 26 }; // scratch
static const Register XMM11 = { 27 }; // scratch
static const Register XMM12 = { 28 }; // scratch
static const Register XMM13 = { 29 }; // scratch
static const Register XMM14 = { 30 }; // scratch
static const Register XMM15 = { 31 }; // scratch
static const Register FP = RBP;
static const Register RZero = { 0 }; // useful in a few places in codegen
static const uint32_t FirstRegNum = 0;
static const uint32_t LastRegNum = 31;
static const Register deprecated_UnknownReg = { 32 }; // XXX: remove eventually, see bug 538924
static const Register UnspecifiedReg = { 32 };
/*
* Micro-templating variable-length opcodes, idea first
* describe by Mike Pall of Luajit.
*
* X86-64 opcode encodings: LSB encodes the length of the
* opcode in bytes, remaining bytes are encoded as 1-7 bytes
* in a single uint64_t value. The value is written as a single
* store into the code stream, and the code pointer is decremented
* by the length. each successive instruction partially overlaps
* the previous one.
*
* emit methods below are able to encode mod/rm, sib, rex, and
* register and small immediate values into these opcode values
* without much branchy code.
*
* these opcodes encapsulate all the const parts of the instruction.
* for example, the alu-immediate opcodes (add, sub, etc) encode
* part of their opcode in the R field of the mod/rm byte; this
* hardcoded value is in the constant below, and the R argument
* to emitrr() is 0. In a few cases, a whole instruction is encoded
* this way (eg callrax).
*
* when a disp32, immI, or imm64 suffix can't fit in an 8-byte
* opcode, then it is written into the code separately and not counted
* in the opcode length.
*/
enum X64Opcode
#if defined(_MSC_VER) && _MSC_VER >= 1400
#pragma warning(disable:4480) // nonstandard extension used: specifying underlying type for enum
: uint64_t
#endif
{
// 64bit opcode constants
// msb lsb len
X64_addqrr = 0xC003480000000003LL, // 64bit add r += b
X64_addqri = 0xC081480000000003LL, // 64bit add r += int64(immI)
X64_addqr8 = 0x00C0834800000004LL, // 64bit add r += int64(imm8)
X64_andqri = 0xE081480000000003LL, // 64bit and r &= int64(immI)
X64_andqr8 = 0x00E0834800000004LL, // 64bit and r &= int64(imm8)
X64_orqri = 0xC881480000000003LL, // 64bit or r |= int64(immI)
X64_orqr8 = 0x00C8834800000004LL, // 64bit or r |= int64(imm8)
X64_xorqri = 0xF081480000000003LL, // 64bit xor r ^= int64(immI)
X64_xorqr8 = 0x00F0834800000004LL, // 64bit xor r ^= int64(imm8)
X64_addlri = 0xC081400000000003LL, // 32bit add r += immI
X64_addlr8 = 0x00C0834000000004LL, // 32bit add r += imm8
X64_andlri = 0xE081400000000003LL, // 32bit and r &= immI
X64_andlr8 = 0x00E0834000000004LL, // 32bit and r &= imm8
X64_orlri = 0xC881400000000003LL, // 32bit or r |= immI
X64_orlr8 = 0x00C8834000000004LL, // 32bit or r |= imm8
X64_sublri = 0xE881400000000003LL, // 32bit sub r -= immI
X64_sublr8 = 0x00E8834000000004LL, // 32bit sub r -= imm8
X64_xorlri = 0xF081400000000003LL, // 32bit xor r ^= immI
X64_xorlr8 = 0x00F0834000000004LL, // 32bit xor r ^= imm8
X64_addrr = 0xC003400000000003LL, // 32bit add r += b
X64_andqrr = 0xC023480000000003LL, // 64bit and r &= b
X64_andrr = 0xC023400000000003LL, // 32bit and r &= b
X64_call = 0x00000000E8000005LL, // near call
X64_callrax = 0xD0FF000000000002LL, // indirect call to addr in rax (no REX)
X64_cmovqno = 0xC0410F4800000004LL, // 64bit conditional mov if (no overflow) r = b
X64_cmovqnae= 0xC0420F4800000004LL, // 64bit conditional mov if (uint <) r = b
X64_cmovqnb = 0xC0430F4800000004LL, // 64bit conditional mov if (uint >=) r = b
X64_cmovqne = 0xC0450F4800000004LL, // 64bit conditional mov if (c) r = b
X64_cmovqna = 0xC0460F4800000004LL, // 64bit conditional mov if (uint <=) r = b
X64_cmovqnbe= 0xC0470F4800000004LL, // 64bit conditional mov if (uint >) r = b
X64_cmovqnge= 0xC04C0F4800000004LL, // 64bit conditional mov if (int <) r = b
X64_cmovqnl = 0xC04D0F4800000004LL, // 64bit conditional mov if (int >=) r = b
X64_cmovqng = 0xC04E0F4800000004LL, // 64bit conditional mov if (int <=) r = b
X64_cmovqnle= 0xC04F0F4800000004LL, // 64bit conditional mov if (int >) r = b
X64_cmovno = 0xC0410F4000000004LL, // 32bit conditional mov if (no overflow) r = b
X64_cmovnae = 0xC0420F4000000004LL, // 32bit conditional mov if (uint <) r = b
X64_cmovnb = 0xC0430F4000000004LL, // 32bit conditional mov if (uint >=) r = b
X64_cmovne = 0xC0450F4000000004LL, // 32bit conditional mov if (c) r = b
X64_cmovna = 0xC0460F4000000004LL, // 32bit conditional mov if (uint <=) r = b
X64_cmovnbe = 0xC0470F4000000004LL, // 32bit conditional mov if (uint >) r = b
X64_cmovnge = 0xC04C0F4000000004LL, // 32bit conditional mov if (int <) r = b
X64_cmovnl = 0xC04D0F4000000004LL, // 32bit conditional mov if (int >=) r = b
X64_cmovng = 0xC04E0F4000000004LL, // 32bit conditional mov if (int <=) r = b
X64_cmovnle = 0xC04F0F4000000004LL, // 32bit conditional mov if (int >) r = b
X64_cmplr = 0xC03B400000000003LL, // 32bit compare r,b
X64_cmpqr = 0xC03B480000000003LL, // 64bit compare r,b
X64_cmplri = 0xF881400000000003LL, // 32bit compare r,immI
X64_cmpqri = 0xF881480000000003LL, // 64bit compare r,int64(immI)
X64_cmplr8 = 0x00F8834000000004LL, // 32bit compare r,imm8
X64_cmpqr8 = 0x00F8834800000004LL, // 64bit compare r,int64(imm8)
X64_cvtsi2sd= 0xC02A0F40F2000005LL, // convert int32 to double r = (double) b
X64_cvtsq2sd= 0xC02A0F48F2000005LL, // convert int64 to double r = (double) b
X64_cvtss2sd= 0xC05A0F40F3000005LL, // convert float to double r = (double) b
X64_cvtsd2ss= 0xC05A0F40F2000005LL, // convert double to float r = (float) b
X64_cvtsd2si= 0xC02D0F40F2000005LL, // convert double to int32 with rounding r = (int32) b
X64_cvttsd2si=0xC02C0F40F2000005LL, // convert double to int32 r = (int32) b
X64_divsd = 0xC05E0F40F2000005LL, // divide scalar double r /= b
X64_mulsd = 0xC0590F40F2000005LL, // multiply scalar double r *= b
X64_addsd = 0xC0580F40F2000005LL, // add scalar double r += b
X64_idiv = 0xF8F7400000000003LL, // 32bit signed div (rax = rdx:rax/r, rdx=rdx:rax%r)
X64_imul = 0xC0AF0F4000000004LL, // 32bit signed mul r *= b
X64_imuli = 0xC069400000000003LL, // 32bit signed mul r = b * immI
X64_imul8 = 0x00C06B4000000004LL, // 32bit signed mul r = b * imm8
X64_jmpi = 0x0000000025FF0006LL, // jump *0(rip)
X64_jmp = 0x00000000E9000005LL, // jump near rel32
X64_jmp8 = 0x00EB000000000002LL, // jump near rel8
X64_jo = 0x00000000800F0006LL, // jump near if overflow
X64_jb = 0x00000000820F0006LL, // jump near if below (uint <)
X64_jae = 0x00000000830F0006LL, // jump near if above or equal (uint >=)
X64_ja = 0x00000000870F0006LL, // jump near if above (uint >)
X64_jbe = 0x00000000860F0006LL, // jump near if below or equal (uint <=)
X64_je = 0x00000000840F0006LL, // near jump if equal
X64_jl = 0x000000008C0F0006LL, // jump near if less (int <)
X64_jge = 0x000000008D0F0006LL, // jump near if greater or equal (int >=)
X64_jg = 0x000000008F0F0006LL, // jump near if greater (int >)
X64_jle = 0x000000008E0F0006LL, // jump near if less or equal (int <=)
X64_jp = 0x000000008A0F0006LL, // jump near if parity (PF == 1)
X64_jneg = 0x0000000001000000LL, // xor with this mask to negate the condition
X64_jo8 = 0x0070000000000002LL, // jump near if overflow
X64_jb8 = 0x0072000000000002LL, // jump near if below (uint <)
X64_jae8 = 0x0073000000000002LL, // jump near if above or equal (uint >=)
X64_ja8 = 0x0077000000000002LL, // jump near if above (uint >)
X64_jbe8 = 0x0076000000000002LL, // jump near if below or equal (uint <=)
X64_je8 = 0x0074000000000002LL, // near jump if equal
X64_jne8 = 0x0075000000000002LL, // jump near if not equal
X64_jl8 = 0x007C000000000002LL, // jump near if less (int <)
X64_jge8 = 0x007D000000000002LL, // jump near if greater or equal (int >=)
X64_jg8 = 0x007F000000000002LL, // jump near if greater (int >)
X64_jle8 = 0x007E000000000002LL, // jump near if less or equal (int <=)
X64_jp8 = 0x007A000000000002LL, // jump near if parity (PF == 1)
X64_jnp8 = 0x007B000000000002LL, // jump near if not parity (PF == 0)
X64_jneg8 = 0x0001000000000000LL, // xor with this mask to negate the condition
X64_leaqrm = 0x00000000808D4807LL, // 64bit load effective addr reg <- disp32+base
X64_lealrm = 0x00000000808D4007LL, // 32bit load effective addr reg <- disp32+base
X64_learip = 0x00000000058D4807LL, // 64bit RIP-relative lea. reg <- disp32+rip (modrm = 00rrr101 = 05)
X64_movlr = 0xC08B400000000003LL, // 32bit mov r <- b
X64_movbmr = 0x0000000080884007LL, // 8bit store r -> [b+d32]
X64_movsmr = 0x8089406600000004LL, // 16bit store r -> [b+d32]
X64_movlmr = 0x0000000080894007LL, // 32bit store r -> [b+d32]
X64_movlrm = 0x00000000808B4007LL, // 32bit load r <- [b+d32]
X64_movqmr = 0x0000000080894807LL, // 64bit store gpr -> [b+d32]
X64_movqspr = 0x0024448948000005LL, // 64bit store gpr -> [rsp+d32] (sib required)
X64_movqr = 0xC08B480000000003LL, // 64bit mov r <- b
X64_movqi = 0xB848000000000002LL, // 64bit mov r <- imm64
X64_movi = 0xB840000000000002LL, // 32bit mov r <- immI
X64_movqi32 = 0xC0C7480000000003LL, // 64bit mov r <- int64(immI)
X64_movapsr = 0xC0280F4000000004LL, // 128bit mov xmm <- xmm
X64_movqrx = 0xC07E0F4866000005LL, // 64bit mov b <- xmm-r (reverses the usual r/b order)
X64_movqxr = 0xC06E0F4866000005LL, // 64bit mov b -> xmm-r
X64_movqrm = 0x00000000808B4807LL, // 64bit load r <- [b+d32]
X64_movsdrr = 0xC0100F40F2000005LL, // 64bit mov xmm-r <- xmm-b (upper 64bits unchanged)
X64_movsdrm = 0x80100F40F2000005LL, // 64bit load xmm-r <- [b+d32] (upper 64 cleared)
X64_movsdmr = 0x80110F40F2000005LL, // 64bit store xmm-r -> [b+d32]
X64_movssrm = 0x80100F40F3000005LL, // 32bit load xmm-r <- [b+d32] (upper 96 cleared)
X64_movssmr = 0x80110F40F3000005LL, // 32bit store xmm-r -> [b+d32]
X64_movsxdr = 0xC063480000000003LL, // sign extend i32 to i64 r = (int64)(int32) b
X64_movzx8 = 0xC0B60F4000000004LL, // zero extend i8 to i64 r = (uint64)(uint8) b
X64_movzx8m = 0x80B60F4000000004LL, // zero extend i8 load to i32 r <- [b+d32]
X64_movzx16m= 0x80B70F4000000004LL, // zero extend i16 load to i32 r <- [b+d32]
X64_movsx8m = 0x80BE0F4000000004LL, // sign extend i8 load to i32 r <- [b+d32]
X64_movsx16m= 0x80BF0F4000000004LL, // sign extend i16 load to i32 r <- [b+d32]
X64_neg = 0xD8F7400000000003LL, // 32bit two's compliment b = -b
X64_nop1 = 0x9000000000000001LL, // one byte NOP
X64_nop2 = 0x9066000000000002LL, // two byte NOP
X64_nop3 = 0x001F0F0000000003LL, // three byte NOP
X64_nop4 = 0x00401F0F00000004LL, // four byte NOP
X64_nop5 = 0x0000441F0F000005LL, // five byte NOP
X64_nop6 = 0x0000441F0F660006LL, // six byte NOP
X64_nop7 = 0x00000000801F0F07LL, // seven byte NOP
X64_not = 0xD0F7400000000003LL, // 32bit ones compliment b = ~b
X64_orlrr = 0xC00B400000000003LL, // 32bit or r |= b
X64_orqrr = 0xC00B480000000003LL, // 64bit or r |= b
X64_popr = 0x5840000000000002LL, // 64bit pop r <- [rsp++]
X64_pushr = 0x5040000000000002LL, // 64bit push r -> [--rsp]
X64_pxor = 0xC0EF0F4066000005LL, // 128bit xor xmm-r ^= xmm-b
X64_ret = 0xC300000000000001LL, // near return from called procedure
X64_sete = 0xC0940F4000000004LL, // set byte if equal (ZF == 1)
X64_seto = 0xC0900F4000000004LL, // set byte if overflow (OF == 1)
X64_setc = 0xC0920F4000000004LL, // set byte if carry (CF == 1)
X64_setl = 0xC09C0F4000000004LL, // set byte if less (int <) (SF != OF)
X64_setle = 0xC09E0F4000000004LL, // set byte if less or equal (int <=) (ZF == 1 || SF != OF)
X64_setg = 0xC09F0F4000000004LL, // set byte if greater (int >) (ZF == 0 && SF == OF)
X64_setge = 0xC09D0F4000000004LL, // set byte if greater or equal (int >=) (SF == OF)
X64_seta = 0xC0970F4000000004LL, // set byte if above (uint >) (CF == 0 && ZF == 0)
X64_setae = 0xC0930F4000000004LL, // set byte if above or equal (uint >=) (CF == 0)
X64_setb = 0xC0920F4000000004LL, // set byte if below (uint <) (CF == 1)
X64_setbe = 0xC0960F4000000004LL, // set byte if below or equal (uint <=) (ZF == 1 || CF == 1)
X64_subsd = 0xC05C0F40F2000005LL, // subtract scalar double r -= b
X64_shl = 0xE0D3400000000003LL, // 32bit left shift r <<= rcx
X64_shlq = 0xE0D3480000000003LL, // 64bit left shift r <<= rcx
X64_shr = 0xE8D3400000000003LL, // 32bit uint right shift r >>= rcx
X64_shrq = 0xE8D3480000000003LL, // 64bit uint right shift r >>= rcx
X64_sar = 0xF8D3400000000003LL, // 32bit int right shift r >>= rcx
X64_sarq = 0xF8D3480000000003LL, // 64bit int right shift r >>= rcx
X64_shli = 0x00E0C14000000004LL, // 32bit left shift r <<= imm8
X64_shlqi = 0x00E0C14800000004LL, // 64bit left shift r <<= imm8
X64_sari = 0x00F8C14000000004LL, // 32bit int right shift r >>= imm8
X64_sarqi = 0x00F8C14800000004LL, // 64bit int right shift r >>= imm8
X64_shri = 0x00E8C14000000004LL, // 32bit uint right shift r >>= imm8
X64_shrqi = 0x00E8C14800000004LL, // 64bit uint right shift r >>= imm8
X64_subqrr = 0xC02B480000000003LL, // 64bit sub r -= b
X64_subrr = 0xC02B400000000003LL, // 32bit sub r -= b
X64_subqri = 0xE881480000000003LL, // 64bit sub r -= int64(immI)
X64_subqr8 = 0x00E8834800000004LL, // 64bit sub r -= int64(imm8)
X64_ucomisd = 0xC02E0F4066000005LL, // unordered compare scalar double
X64_xorqrr = 0xC033480000000003LL, // 64bit xor r &= b
X64_xorrr = 0xC033400000000003LL, // 32bit xor r &= b
X64_xorpd = 0xC0570F4066000005LL, // 128bit xor xmm (two packed doubles)
X64_xorps = 0xC0570F4000000004LL, // 128bit xor xmm (four packed singles), one byte shorter
X64_xorpsm = 0x05570F4000000004LL, // 128bit xor xmm, [rip+disp32]
X64_xorpsa = 0x2504570F40000005LL, // 128bit xor xmm, [disp32]
X64_inclmRAX= 0x00FF000000000002LL, // incl (%rax)
X64_jmpx = 0xC524ff4000000004LL, // jmp [d32+x*8]
X64_jmpxb = 0xC024ff4000000004LL, // jmp [b+x*8]
X64_movqmi = 0x80C7480000000003LL, // 32bit signed extended to 64-bit store imm -> qword ptr[b+disp32]
X64_movlmi = 0x80C7400000000003LL, // 32bit store imm -> dword ptr[b+disp32]
X64_movsmi = 0x80C7406600000004LL, // 16bit store imm -> word ptr[b+disp32]
X64_movbmi = 0x80C6400000000003LL, // 8bit store imm -> byte ptr[b+disp32]
X86_and8r = 0xC022000000000002LL, // and rl,rh
X86_sete = 0xC0940F0000000003LL, // no-rex version of X64_sete
X86_setnp = 0xC09B0F0000000003LL // no-rex set byte if odd parity (ordered fcmp result) (PF == 0)
};
typedef uint32_t RegisterMask;
static const RegisterMask GpRegs = 0xffff;
static const RegisterMask FpRegs = 0xffff0000;
#ifdef _WIN64
static const RegisterMask SavedRegs = 1<<REGNUM(RBX) | 1<<REGNUM(RSI) | 1<<REGNUM(RDI) |
1<<REGNUM(R12) | 1<<REGNUM(R13) | 1<<REGNUM(R14) |
1<<REGNUM(R15);
static const int NumSavedRegs = 7; // rbx, rsi, rdi, r12-15
static const int NumArgRegs = 4;
#else
static const RegisterMask SavedRegs = 1<<REGNUM(RBX) | 1<<REGNUM(R12) | 1<<REGNUM(R13) |
1<<REGNUM(R14) | 1<<REGNUM(R15);
static const int NumSavedRegs = 5; // rbx, r12-15
static const int NumArgRegs = 6;
#endif
// Warning: when talking about single byte registers, RSP/RBP/RSI/RDI are
// actually synonyms for AH/CH/DH/BH. So this value means "any
// single-byte GpReg except AH/CH/DH/BH".
static const RegisterMask SingleByteStoreRegs = GpRegs & ~(1<<REGNUM(RSP) | 1<<REGNUM(RBP) |
1<<REGNUM(RSI) | 1<<REGNUM(RDI));
static inline bool IsFpReg(Register r) {
return ((1<<REGNUM(r)) & FpRegs) != 0;
}
static inline bool IsGpReg(Register r) {
return ((1<<REGNUM(r)) & GpRegs) != 0;
}
verbose_only( extern const char* regNames[]; )
verbose_only( extern const char* gpRegNames32[]; )
verbose_only( extern const char* gpRegNames8[]; )
verbose_only( extern const char* gpRegNames8hi[]; )
#define DECLARE_PLATFORM_STATS()
#define DECLARE_PLATFORM_REGALLOC()
#define DECLARE_PLATFORM_ASSEMBLER() \
const static Register argRegs[NumArgRegs], retRegs[1]; \
void underrunProtect(ptrdiff_t bytes); \
void nativePageReset(); \
void nativePageSetup(); \
bool hardenNopInsertion(const Config& /*c*/) { return false; } \
void asm_qbinop(LIns*); \
void MR(Register, Register);\
void JMP(NIns*);\
void JMPl(NIns*);\
void emit(uint64_t op);\
void emit8(uint64_t op, int64_t val);\
void emit_target8(size_t underrun, uint64_t op, NIns* target);\
void emit_target32(size_t underrun, uint64_t op, NIns* target);\
void emit_target64(size_t underrun, uint64_t op, NIns* target); \
void emitrr(uint64_t op, Register r, Register b);\
void emitrxb(uint64_t op, Register r, Register x, Register b);\
void emitxb(uint64_t op, Register x, Register b) { emitrxb(op, RZero, x, b); }\
void emitrr8(uint64_t op, Register r, Register b);\
void emitr(uint64_t op, Register b) { emitrr(op, RZero, b); }\
void emitr8(uint64_t op, Register b) { emitrr8(op, RZero, b); }\
void emitprr(uint64_t op, Register r, Register b);\
void emitrm8(uint64_t op, Register r, int32_t d, Register b);\
void emitrm(uint64_t op, Register r, int32_t d, Register b);\
void emitrm_wide(uint64_t op, Register r, int32_t d, Register b);\
uint64_t emit_disp32(uint64_t op, int32_t d);\
void emitprm(uint64_t op, Register r, int32_t d, Register b);\
void emitrr_imm(uint64_t op, Register r, Register b, int32_t imm);\
void emitr_imm64(uint64_t op, Register r, uint64_t imm);\
void emitrm_imm32(uint64_t op, Register r, int32_t d, int32_t imm);\
void emitprm_imm16(uint64_t op, Register r, int32_t d, int32_t imm);\
void emitrm_imm8(uint64_t op, Register r, int32_t d, int32_t imm);\
void emitrxb_imm(uint64_t op, Register r, Register x, Register b, int32_t imm);\
void emitr_imm(uint64_t op, Register r, int32_t imm) { emitrr_imm(op, RZero, r, imm); }\
void emitr_imm8(uint64_t op, Register b, int32_t imm8);\
void emitxm_abs(uint64_t op, Register r, int32_t addr32);\
void emitxm_rel(uint64_t op, Register r, NIns* addr64);\
bool isTargetWithinS8(NIns* target);\
bool isTargetWithinS32(NIns* target);\
void asm_immi(Register r, int32_t v, bool canClobberCCs);\
void asm_immq(Register r, uint64_t v, bool canClobberCCs);\
void asm_immd(Register r, uint64_t v, bool canClobberCCs);\
void asm_regarg(ArgType, LIns*, Register);\
void asm_stkarg(ArgType, LIns*, int);\
void asm_shift(LIns*);\
void asm_shift_imm(LIns*);\
void asm_arith_imm(LIns*);\
void beginOp1Regs(LIns *ins, RegisterMask allow, Register &rr, Register &ra);\
void beginOp2Regs(LIns *ins, RegisterMask allow, Register &rr, Register &ra, Register &rb);\
void endOpRegs(LIns *ins, Register rr, Register ra);\
void beginLoadRegs(LIns *ins, RegisterMask allow, Register &rr, int32_t &d, Register &rb);\
void endLoadRegs(LIns *ins);\
void dis(NIns *p, int bytes);\
void asm_cmp(LIns*);\
void asm_cmpi(LIns*);\
void asm_cmpi_imm(LIns*);\
void asm_cmpd(LIns*);\
NIns* asm_branch_helper(bool, LIns*, NIns*);\
NIns* asm_branchi_helper(bool, LIns*, NIns*);\
NIns* asm_branchd_helper(bool, LIns*, NIns*);\
void asm_div(LIns *ins);\
void asm_div_mod(LIns *ins);\
int max_stk_used;\
void PUSHR(Register r);\
void POPR(Register r);\
void NOT(Register r);\
void NEG(Register r);\
void IDIV(Register r);\
void SHR(Register r);\
void SAR(Register r);\
void SHL(Register r);\
void SHRQ(Register r);\
void SARQ(Register r);\
void SHLQ(Register r);\
void SHRI(Register r, int i);\
void SARI(Register r, int i);\
void SHLI(Register r, int i);\
void SHRQI(Register r, int i);\
void SARQI(Register r, int i);\
void SHLQI(Register r, int i);\
void SETE(Register r);\
void SETL(Register r);\
void SETLE(Register r);\
void SETG(Register r);\
void SETGE(Register r);\
void SETB(Register r);\
void SETBE(Register r);\
void SETA(Register r);\
void SETAE(Register r);\
void SETO(Register r);\
void ADDRR(Register l, Register r);\
void SUBRR(Register l, Register r);\
void ANDRR(Register l, Register r);\
void ORLRR(Register l, Register r);\
void XORRR(Register l, Register r);\
void IMUL(Register l, Register r);\
void CMPLR(Register l, Register r);\
void MOVLR(Register l, Register r);\
void ADDQRR(Register l, Register r);\
void SUBQRR(Register l, Register r);\
void ANDQRR(Register l, Register r);\
void ORQRR(Register l, Register r);\
void XORQRR(Register l, Register r);\
void CMPQR(Register l, Register r);\
void MOVQR(Register l, Register r);\
void MOVAPSR(Register l, Register r);\
void CMOVNO(Register l, Register r);\
void CMOVNE(Register l, Register r);\
void CMOVNL(Register l, Register r);\
void CMOVNLE(Register l, Register r);\
void CMOVNG(Register l, Register r);\
void CMOVNGE(Register l, Register r);\
void CMOVNB(Register l, Register r);\
void CMOVNBE(Register l, Register r);\
void CMOVNA(Register l, Register r);\
void CMOVNAE(Register l, Register r);\
void CMOVQNO(Register l, Register r);\
void CMOVQNE(Register l, Register r);\
void CMOVQNL(Register l, Register r);\
void CMOVQNLE(Register l, Register r);\
void CMOVQNG(Register l, Register r);\
void CMOVQNGE(Register l, Register r);\
void CMOVQNB(Register l, Register r);\
void CMOVQNBE(Register l, Register r);\
void CMOVQNA(Register l, Register r);\
void CMOVQNAE(Register l, Register r);\
void MOVSXDR(Register l, Register r);\
void MOVZX8(Register l, Register r);\
void XORPS(Register r);\
void XORPS(Register l, Register r);\
void DIVSD(Register l, Register r);\
void MULSD(Register l, Register r);\
void ADDSD(Register l, Register r);\
void SUBSD(Register l, Register r);\
void CVTSQ2SD(Register l, Register r);\
void CVTSI2SD(Register l, Register r);\
void CVTSS2SD(Register l, Register r);\
void CVTSD2SS(Register l, Register r);\
void CVTSD2SI(Register l, Register r);\
void CVTTSD2SI(Register l, Register r);\
void UCOMISD(Register l, Register r);\
void MOVQRX(Register l, Register r);\
void MOVQXR(Register l, Register r);\
void MOVI(Register r, int32_t i32);\
void ADDLRI(Register r, int32_t i32);\
void SUBLRI(Register r, int32_t i32);\
void ANDLRI(Register r, int32_t i32);\
void ORLRI(Register r, int32_t i32);\
void XORLRI(Register r, int32_t i32);\
void CMPLRI(Register r, int32_t i32);\
void ADDQRI(Register r, int32_t i32);\
void SUBQRI(Register r, int32_t i32);\
void ANDQRI(Register r, int32_t i32);\
void ORQRI(Register r, int32_t i32);\
void XORQRI(Register r, int32_t i32);\
void CMPQRI(Register r, int32_t i32);\
void MOVQI32(Register r, int32_t i32);\
void ADDLR8(Register r, int32_t i8);\
void SUBLR8(Register r, int32_t i8);\
void ANDLR8(Register r, int32_t i8);\
void ORLR8(Register r, int32_t i8);\
void XORLR8(Register r, int32_t i8);\
void CMPLR8(Register r, int32_t i8);\
void ADDQR8(Register r, int32_t i8);\
void SUBQR8(Register r, int32_t i8);\
void ANDQR8(Register r, int32_t i8);\
void ORQR8(Register r, int32_t i8);\
void XORQR8(Register r, int32_t i8);\
void CMPQR8(Register r, int32_t i8);\
void IMULI(Register l, Register r, int32_t i32);\
void MOVQI(Register r, uint64_t u64);\
void LEARIP(Register r, int32_t d);\
void LEALRM(Register r, int d, Register b);\
void LEAQRM(Register r, int d, Register b);\
void MOVLRM(Register r, int d, Register b);\
void MOVQRM(Register r, int d, Register b);\
void MOVBMR(Register r, int d, Register b);\
void MOVSMR(Register r, int d, Register b);\
void MOVLMR(Register r, int d, Register b);\
void MOVQMR(Register r, int d, Register b);\
void MOVZX8M(Register r, int d, Register b);\
void MOVZX16M(Register r, int d, Register b);\
void MOVSX8M(Register r, int d, Register b);\
void MOVSX16M(Register r, int d, Register b);\
void MOVSDRM(Register r, int d, Register b);\
void MOVSDMR(Register r, int d, Register b);\
void MOVSSMR(Register r, int d, Register b);\
void MOVSSRM(Register r, int d, Register b);\
void JMP8(size_t n, NIns* t);\
void JMP32(size_t n, NIns* t);\
void JMP64(size_t n, NIns* t);\
void JMPX(Register indexreg, NIns** table);\
void JMPXB(Register indexreg, Register tablereg);\
void JO(size_t n, NIns* t);\
void JE(size_t n, NIns* t);\
void JL(size_t n, NIns* t);\
void JLE(size_t n, NIns* t);\
void JG(size_t n, NIns* t);\
void JGE(size_t n, NIns* t);\
void JB(size_t n, NIns* t);\
void JBE(size_t n, NIns* t);\
void JA(size_t n, NIns* t);\
void JAE(size_t n, NIns* t);\
void JP(size_t n, NIns* t);\
void JNO(size_t n, NIns* t);\
void JNE(size_t n, NIns* t);\
void JNL(size_t n, NIns* t);\
void JNLE(size_t n, NIns* t);\
void JNG(size_t n, NIns* t);\
void JNGE(size_t n, NIns* t);\
void JNB(size_t n, NIns* t);\
void JNBE(size_t n, NIns* t);\
void JNA(size_t n, NIns* t);\
void JNAE(size_t n, NIns* t);\
void JO8(size_t n, NIns* t);\
void JE8(size_t n, NIns* t);\
void JL8(size_t n, NIns* t);\
void JLE8(size_t n, NIns* t);\
void JG8(size_t n, NIns* t);\
void JGE8(size_t n, NIns* t);\
void JB8(size_t n, NIns* t);\
void JBE8(size_t n, NIns* t);\
void JA8(size_t n, NIns* t);\
void JAE8(size_t n, NIns* t);\
void JP8(size_t n, NIns* t);\
void JNO8(size_t n, NIns* t);\
void JNE8(size_t n, NIns* t);\
void JNL8(size_t n, NIns* t);\
void JNLE8(size_t n, NIns* t);\
void JNG8(size_t n, NIns* t);\
void JNGE8(size_t n, NIns* t);\
void JNB8(size_t n, NIns* t);\
void JNBE8(size_t n, NIns* t);\
void JNA8(size_t n, NIns* t);\
void JNAE8(size_t n, NIns* t);\
void CALL(size_t n, NIns* t);\
void CALLRAX();\
void RET();\
void MOVQSPR(int d, Register r);\
void XORPSA(Register r, int32_t i32);\
void XORPSM(Register r, NIns* a64);\
void X86_AND8R(Register r);\
void X86_SETNP(Register r);\
void X86_SETE(Register r);\
void MOVQMI(Register base, int disp, int32_t imm32); \
void MOVLMI(Register base, int disp, int32_t imm32); \
void MOVSMI(Register base, int disp, int32_t imm16); \
void MOVBMI(Register base, int disp, int32_t imm8); \
const int LARGEST_UNDERRUN_PROT = 32; // largest value passed to underrunProtect
typedef uint8_t NIns;
// Bytes of icache to flush after Assembler::patch
const size_t LARGEST_BRANCH_PATCH = 16 * sizeof(NIns);
} // namespace nanojit
#endif // __nanojit_NativeX64__
|