mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2024-11-23 04:09:40 +00:00
487 lines
9.4 KiB
Ruby
487 lines
9.4 KiB
Ruby
# Copyright (C) 2011-2020 Apple Inc. All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
|
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
# THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
require "config"
|
|
require "set"
|
|
|
|
# Interesting invariant, which we take advantage of: branching instructions
|
|
# always begin with "b", and no non-branching instructions begin with "b".
|
|
# Terminal instructions are "jmp" and "ret".
|
|
|
|
MACRO_INSTRUCTIONS =
|
|
[
|
|
"emit",
|
|
"addi",
|
|
"andi",
|
|
"andf",
|
|
"andd",
|
|
"lshifti",
|
|
"lshiftp",
|
|
"lshiftq",
|
|
"muli",
|
|
"negi",
|
|
"negp",
|
|
"negq",
|
|
"noti",
|
|
"ori",
|
|
"orf",
|
|
"ord",
|
|
"orh",
|
|
"rshifti",
|
|
"urshifti",
|
|
"rshiftp",
|
|
"urshiftp",
|
|
"rshiftq",
|
|
"urshiftq",
|
|
"lrotatei",
|
|
"lrotateq",
|
|
"rrotatei",
|
|
"rrotateq",
|
|
"subi",
|
|
"xori",
|
|
"loadi",
|
|
"loadis",
|
|
"loadb",
|
|
"loadbsi",
|
|
"loadbsq",
|
|
"loadh",
|
|
"loadhsi",
|
|
"loadhsq",
|
|
"storei",
|
|
"storeh",
|
|
"storeb",
|
|
"loadf",
|
|
"loadd",
|
|
"moved",
|
|
"storef",
|
|
"stored",
|
|
"addf",
|
|
"addd",
|
|
"divf",
|
|
"divd",
|
|
"subf",
|
|
"subd",
|
|
"mulf",
|
|
"muld",
|
|
"sqrtf",
|
|
"sqrtd",
|
|
"floorf",
|
|
"floord",
|
|
"roundf",
|
|
"roundd",
|
|
"truncatef",
|
|
"truncated",
|
|
"truncatef2i",
|
|
"truncatef2q",
|
|
"truncated2q",
|
|
"truncated2i",
|
|
"truncatef2is",
|
|
"truncated2is",
|
|
"truncatef2qs",
|
|
"truncated2qs",
|
|
"ci2d",
|
|
"ci2ds",
|
|
"ci2f",
|
|
"ci2fs",
|
|
"cq2f",
|
|
"cq2fs",
|
|
"cq2d",
|
|
"cq2ds",
|
|
"cd2f",
|
|
"cf2d",
|
|
"fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
|
|
"fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
|
|
"fq2d",
|
|
"fd2q",
|
|
"bdeq",
|
|
"bdneq",
|
|
"bdgt",
|
|
"bdgteq",
|
|
"bdlt",
|
|
"bdlteq",
|
|
"bdequn",
|
|
"bdnequn",
|
|
"bdgtun",
|
|
"bdgtequn",
|
|
"bdltun",
|
|
"bdltequn",
|
|
"bfeq",
|
|
"bfgt",
|
|
"bflt",
|
|
"bfgtun",
|
|
"bfgtequn",
|
|
"bfltun",
|
|
"bfltequn",
|
|
"btd2i",
|
|
"td2i",
|
|
"bcd2i",
|
|
"movdz",
|
|
"pop",
|
|
"push",
|
|
"move",
|
|
"sxi2q",
|
|
"zxi2q",
|
|
"sxb2i",
|
|
"sxh2i",
|
|
"sxb2q",
|
|
"sxh2q",
|
|
"nop",
|
|
"bieq",
|
|
"bineq",
|
|
"bia",
|
|
"biaeq",
|
|
"bib",
|
|
"bibeq",
|
|
"bigt",
|
|
"bigteq",
|
|
"bilt",
|
|
"bilteq",
|
|
"bbeq",
|
|
"bbneq",
|
|
"bba",
|
|
"bbaeq",
|
|
"bbb",
|
|
"bbbeq",
|
|
"bbgt",
|
|
"bbgteq",
|
|
"bblt",
|
|
"bblteq",
|
|
"btis",
|
|
"btiz",
|
|
"btinz",
|
|
"btbs",
|
|
"btbz",
|
|
"btbnz",
|
|
"jmp",
|
|
"baddio",
|
|
"baddis",
|
|
"baddiz",
|
|
"baddinz",
|
|
"bsubio",
|
|
"bsubis",
|
|
"bsubiz",
|
|
"bsubinz",
|
|
"bmulio",
|
|
"bmulis",
|
|
"bmuliz",
|
|
"bmulinz",
|
|
"borio",
|
|
"boris",
|
|
"boriz",
|
|
"borinz",
|
|
"break",
|
|
"call",
|
|
"ret",
|
|
"cbeq",
|
|
"cbneq",
|
|
"cba",
|
|
"cbaeq",
|
|
"cbb",
|
|
"cbbeq",
|
|
"cbgt",
|
|
"cbgteq",
|
|
"cblt",
|
|
"cblteq",
|
|
"cieq",
|
|
"cineq",
|
|
"cia",
|
|
"ciaeq",
|
|
"cib",
|
|
"cibeq",
|
|
"cigt",
|
|
"cigteq",
|
|
"cilt",
|
|
"cilteq",
|
|
"tis",
|
|
"tiz",
|
|
"tinz",
|
|
"tbs",
|
|
"tbz",
|
|
"tbnz",
|
|
"tps",
|
|
"tpz",
|
|
"tpnz",
|
|
"peek",
|
|
"poke",
|
|
"bpeq",
|
|
"bpneq",
|
|
"bpa",
|
|
"bpaeq",
|
|
"bpb",
|
|
"bpbeq",
|
|
"bpgt",
|
|
"bpgteq",
|
|
"bplt",
|
|
"bplteq",
|
|
"addp",
|
|
"mulp",
|
|
"andp",
|
|
"orp",
|
|
"subp",
|
|
"xorp",
|
|
"loadp",
|
|
"cpeq",
|
|
"cpneq",
|
|
"cpa",
|
|
"cpaeq",
|
|
"cpb",
|
|
"cpbeq",
|
|
"cpgt",
|
|
"cpgteq",
|
|
"cplt",
|
|
"cplteq",
|
|
"storep",
|
|
"btps",
|
|
"btpz",
|
|
"btpnz",
|
|
"baddpo",
|
|
"baddps",
|
|
"baddpz",
|
|
"baddpnz",
|
|
"tqs",
|
|
"tqz",
|
|
"tqnz",
|
|
"bqeq",
|
|
"bqneq",
|
|
"bqa",
|
|
"bqaeq",
|
|
"bqb",
|
|
"bqbeq",
|
|
"bqgt",
|
|
"bqgteq",
|
|
"bqlt",
|
|
"bqlteq",
|
|
"addq",
|
|
"mulq",
|
|
"andq",
|
|
"orq",
|
|
"subq",
|
|
"xorq",
|
|
"loadq",
|
|
"cqeq",
|
|
"cqneq",
|
|
"cqa",
|
|
"cqaeq",
|
|
"cqb",
|
|
"cqbeq",
|
|
"cqgt",
|
|
"cqgteq",
|
|
"cqlt",
|
|
"cqlteq",
|
|
"storeq",
|
|
"btqs",
|
|
"btqz",
|
|
"btqnz",
|
|
"baddqo",
|
|
"baddqs",
|
|
"baddqz",
|
|
"baddqnz",
|
|
"bo",
|
|
"bs",
|
|
"bz",
|
|
"bnz",
|
|
"leai",
|
|
"leap",
|
|
"memfence",
|
|
"tagCodePtr",
|
|
"tagReturnAddress",
|
|
"untagReturnAddress",
|
|
"removeCodePtrTag",
|
|
"untagArrayPtr",
|
|
"tzcnti",
|
|
"tzcntq",
|
|
"lzcnti",
|
|
"lzcntq",
|
|
"absf",
|
|
"absd",
|
|
"negf",
|
|
"negd",
|
|
"ceilf",
|
|
"ceild",
|
|
"cfeq",
|
|
"cdeq",
|
|
"cfneq",
|
|
"cfnequn",
|
|
"cdneq",
|
|
"cdnequn",
|
|
"cflt",
|
|
"cdlt",
|
|
"cflteq",
|
|
"cdlteq",
|
|
"cfgt",
|
|
"cdgt",
|
|
"cfgteq",
|
|
"cdgteq",
|
|
"fi2f",
|
|
"ff2i",
|
|
"tls_loadp",
|
|
"tls_storep",
|
|
]
|
|
|
|
X86_INSTRUCTIONS =
|
|
[
|
|
"cdqi",
|
|
"idivi",
|
|
"udivi",
|
|
"cqoq",
|
|
"idivq",
|
|
"udivq",
|
|
"notq",
|
|
"atomicxchgaddb",
|
|
"atomicxchgaddh",
|
|
"atomicxchgaddi",
|
|
"atomicxchgaddq",
|
|
"atomicxchgsubb",
|
|
"atomicxchgsubh",
|
|
"atomicxchgsubi",
|
|
"atomicxchgsubq",
|
|
"atomicxchgb",
|
|
"atomicxchgh",
|
|
"atomicxchgi",
|
|
"atomicxchgq",
|
|
"batomicweakcasb",
|
|
"batomicweakcash",
|
|
"batomicweakcasi",
|
|
"batomicweakcasq",
|
|
"atomicweakcasb",
|
|
"atomicweakcash",
|
|
"atomicweakcasi",
|
|
"atomicweakcasq",
|
|
"atomicloadb",
|
|
"atomicloadh",
|
|
"atomicloadi",
|
|
"atomicloadq",
|
|
"fence",
|
|
]
|
|
|
|
ARM_INSTRUCTIONS =
|
|
[
|
|
"clrbp",
|
|
"mvlbl",
|
|
"globaladdr"
|
|
]
|
|
|
|
ARM64_INSTRUCTIONS =
|
|
[
|
|
"bfiq", # Bit field insert <source reg> <last bit written> <width immediate> <dest reg>
|
|
"pcrtoaddr", # Address from PC relative offset - adr instruction
|
|
"globaladdr",
|
|
"divi",
|
|
"divis",
|
|
"divq",
|
|
"divqs",
|
|
"notq",
|
|
"loadlinkacqb",
|
|
"loadlinkacqh",
|
|
"loadlinkacqi",
|
|
"loadlinkacqq",
|
|
"storecondrelb",
|
|
"storecondrelh",
|
|
"storecondreli",
|
|
"storecondrelq",
|
|
"fence",
|
|
# They are available only if Atomic LSE is supported.
|
|
"atomicxchgaddb",
|
|
"atomicxchgaddh",
|
|
"atomicxchgaddi",
|
|
"atomicxchgaddq",
|
|
"atomicxchgclearb",
|
|
"atomicxchgclearh",
|
|
"atomicxchgcleari",
|
|
"atomicxchgclearq",
|
|
"atomicxchgorb",
|
|
"atomicxchgorh",
|
|
"atomicxchgori",
|
|
"atomicxchgorq",
|
|
"atomicxchgxorb",
|
|
"atomicxchgxorh",
|
|
"atomicxchgxori",
|
|
"atomicxchgxorq",
|
|
"atomicxchgb",
|
|
"atomicxchgh",
|
|
"atomicxchgi",
|
|
"atomicxchgq",
|
|
"atomicweakcasb",
|
|
"atomicweakcash",
|
|
"atomicweakcasi",
|
|
"atomicweakcasq",
|
|
"atomicloadb",
|
|
"atomicloadh",
|
|
"atomicloadi",
|
|
"atomicloadq",
|
|
]
|
|
|
|
RISC_INSTRUCTIONS =
|
|
[
|
|
"smulli", # Multiply two 32-bit words and produce a 64-bit word
|
|
"addis", # Add integers and set a flag.
|
|
"subis", # Same, but for subtraction.
|
|
"oris", # Same, but for bitwise or.
|
|
"addps" # addis but for pointers.
|
|
]
|
|
|
|
MIPS_INSTRUCTIONS =
|
|
[
|
|
"la",
|
|
"movz",
|
|
"movn",
|
|
"setcallreg",
|
|
"slt",
|
|
"sltu",
|
|
"pichdr"
|
|
]
|
|
|
|
CXX_INSTRUCTIONS =
|
|
[
|
|
"cloopCrash", # no operands
|
|
"cloopCallJSFunction", # operands: callee
|
|
"cloopCallNative", # operands: callee
|
|
"cloopCallSlowPath", # operands: callTarget, currentFrame, currentPC
|
|
"cloopCallSlowPathVoid", # operands: callTarget, currentFrame, currentPC
|
|
|
|
# For debugging only:
|
|
# Takes no operands but simply emits whatever follows in // comments as
|
|
# a line of C++ code in the generated LLIntAssembly.h file. This can be
|
|
# used to insert instrumentation into the interpreter loop to inspect
|
|
# variables of interest. Do not leave these instructions in production
|
|
# code.
|
|
"cloopDo", # no operands
|
|
]
|
|
|
|
INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM_INSTRUCTIONS + ARM64_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + CXX_INSTRUCTIONS
|
|
|
|
INSTRUCTION_SET = INSTRUCTIONS.to_set
|
|
|
|
def isBranch(instruction)
|
|
instruction =~ /^b/
|
|
end
|
|
|
|
def hasFallThrough(instruction)
|
|
instruction != "ret" and instruction != "jmp"
|
|
end
|
|
|
|
def isPowerOfTwo(value)
|
|
return false if value <= 0
|
|
(value & (value - 1)).zero?
|
|
end
|