diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/b3/B3Opcode.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/b3/B3Opcode.h')
-rw-r--r-- | Source/JavaScriptCore/b3/B3Opcode.h | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/b3/B3Opcode.h b/Source/JavaScriptCore/b3/B3Opcode.h new file mode 100644 index 000000000..956dba99a --- /dev/null +++ b/Source/JavaScriptCore/b3/B3Opcode.h @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2015-2016 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. ``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 + * 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. + */ + +#pragma once + +#if ENABLE(B3_JIT) + +#include "B3Type.h" +#include <wtf/Optional.h> +#include <wtf/StdLibExtras.h> + +namespace JSC { namespace B3 { + +// Warning: In B3, an Opcode is just one part of a Kind. Kind is used the way that an opcode +// would be used in simple IRs. See B3Kind.h. + +enum Opcode : int16_t { + // A no-op that returns Void, useful for when you want to remove a value. + Nop, + + // Polymorphic identity, usable with any value type. + Identity, + + // Constants. Use the ConstValue* classes. Constants exist in the control flow, so that we can + // reason about where we would construct them. Large constants are expensive to create. + Const32, + Const64, + ConstDouble, + ConstFloat, + + // B3 supports non-SSA variables. These are accessed using Get and Set opcodes. Use the + // VariableValue class. It's a good idea to run fixSSA() to turn these into SSA. The + // optimizer will do that eventually, but if your input tends to use these opcodes, you + // should run fixSSA() directly before launching the optimizer. + Set, + Get, + + // Gets the base address of a StackSlot. + SlotBase, + + // The magical argument register. This is viewed as executing at the top of the program + // regardless of where in control flow you put it, and the compiler takes care to ensure that we + // don't clobber the value by register allocation or calls (either by saving the argument to the + // stack or preserving it in a callee-save register). Use the ArgumentRegValue class. The return + // type is either pointer() (for GPRs) or Double (for FPRs). + ArgumentReg, + + // The frame pointer. You can put this anywhere in control flow but it will always yield the + // frame pointer, with a caveat: if our compiler changes the frame pointer temporarily for some + // silly reason, the FramePointer intrinsic will return where the frame pointer *should* be not + // where it happens to be right now. + FramePointer, + + // Polymorphic math, usable with any value type. + Add, + Sub, + Mul, + Div, // All bets are off as to what will happen when you execute this for -2^31/-1 and x/0. + UDiv, + Mod, // All bets are off as to what will happen when you execute this for -2^31%-1 and x%0. + UMod, + + + // Polymorphic negation. Note that we only need this for floating point, since integer negation + // is exactly like Sub(0, x). But that's not true for floating point. Sub(0, 0) is 0, while + // Neg(0) is -0. Also, we canonicalize Sub(0, x) into Neg(x) in case of integers. + Neg, + + // Integer math. + BitAnd, + BitOr, + BitXor, + Shl, + SShr, // Arithmetic Shift. + ZShr, // Logical Shift. + RotR, // Rotate Right. + RotL, // Rotate Left. + Clz, // Count leading zeros. + + // Floating point math. + Abs, + Ceil, + Floor, + Sqrt, + + // Casts and such. + // Bitwise Cast of Double->Int64 or Int64->Double + BitwiseCast, + // Takes and returns Int32: + SExt8, + SExt16, + // Takes Int32 and returns Int64: + SExt32, + ZExt32, + // Does a bitwise truncation of Int64->Int32 and Double->Float: + Trunc, + // Takes ints and returns floating point value. Note that we don't currently provide the opposite operation, + // because double-to-int conversions have weirdly different semantics on different platforms. Use + // a patchpoint if you need to do that. + IToD, + IToF, + // Convert between double and float. + FloatToDouble, + DoubleToFloat, + + // Polymorphic comparisons, usable with any value type. Returns int32 0 or 1. Note that "Not" + // is just Equal(x, 0), and "ToBoolean" is just NotEqual(x, 0). + Equal, + NotEqual, + LessThan, + GreaterThan, + LessEqual, + GreaterEqual, + + // Integer comparisons. Returns int32 0 or 1. + Above, + Below, + AboveEqual, + BelowEqual, + + // Unordered floating point compare: values are equal or either one is NaN. + EqualOrUnordered, + + // SSA form of conditional move. The first child is evaluated for truthiness. If true, the second child + // is returned. Otherwise, the third child is returned. + Select, + + // Memory loads. Opcode indicates how we load and the loaded type. These use MemoryValue. + // These return Int32: + Load8Z, + Load8S, + Load16Z, + Load16S, + // This returns whatever the return type is: + Load, + + // Memory stores. Opcode indicates how the value is stored. These use MemoryValue. + // These take an Int32 value: + Store8, + Store16, + // This is a polymorphic store for Int32, Int64, Float, and Double. + Store, + + // This is used to compute the actual address of a Wasm memory operation. It takes an IntPtr + // and a pinned register then computes the appropriate IntPtr address. For the use-case of + // Wasm it is important that the first child initially be a ZExt32 so the top bits are cleared. + // We do WasmAddress(ZExt32(ptr), ...) so that we can avoid generating extraneous moves in Air. + WasmAddress, + + // This is used to represent standalone fences - i.e. fences that are not part of other + // instructions. It's expressive enough to expose mfence on x86 and dmb ish/ishst on ARM. On + // x86, it also acts as a compiler store-store fence in those cases where it would have been a + // dmb ishst on ARM. + Fence, + + // This is a regular ordinary C function call, using the system C calling convention. Make sure + // that the arguments are passed using the right types. The first argument is the callee. + CCall, + + // This is a patchpoint. Use the PatchpointValue class. This is viewed as behaving like a call, + // but only emits code via a code generation callback. That callback gets to emit code inline. + // You can pass a stackmap along with constraints on how each stackmap argument must be passed. + // It's legal to request that a stackmap argument is in some register and it's legal to request + // that a stackmap argument is at some offset from the top of the argument passing area on the + // stack. + Patchpoint, + + // Checked math. Use the CheckValue class. Like a Patchpoint, this takes a code generation + // callback. That callback gets to emit some code after the epilogue, and gets to link the jump + // from the check, and the choice of registers. You also get to supply a stackmap. Note that you + // are not allowed to jump back into the mainline code from your slow path, since the compiler + // will assume that the execution of these instructions proves that overflow didn't happen. For + // example, if you have two CheckAdd's: + // + // a = CheckAdd(x, y) + // b = CheckAdd(x, y) + // + // Then it's valid to change this to: + // + // a = CheckAdd(x, y) + // b = Identity(a) + // + // This is valid regardless of the callbacks used by the two CheckAdds. They may have different + // callbacks. Yet, this transformation is valid even if they are different because we know that + // after the first CheckAdd executes, the second CheckAdd could not have possibly taken slow + // path. Therefore, the second CheckAdd's callback is irrelevant. + // + // Note that the first two children of these operations have ValueRep's as input constraints but do + // not have output constraints. + CheckAdd, + CheckSub, + CheckMul, + + // Check that side-exits. Use the CheckValue class. Like CheckAdd and friends, this has a + // stackmap with a generation callback. This takes an int argument that this branches on, with + // full branch fusion in the instruction selector. A true value jumps to the generator's slow + // path. Note that the predicate child is has both an input ValueRep. The input constraint must be + // WarmAny. It will not have an output constraint. + Check, + + // Special Wasm opcode that takes a Int32, a special pinned gpr and an offset. This node exists + // to allow us to CSE WasmBoundsChecks if both use the same pointer and one dominates the other. + // Without some such node B3 would not have enough information about the inner workings of wasm + // to be able to perform such optimizations. + WasmBoundsCheck, + + // SSA support, in the style of DFG SSA. + Upsilon, // This uses the UpsilonValue class. + Phi, + + // Jump. + Jump, + + // Polymorphic branch, usable with any integer type. Branches if not equal to zero. The 0-index + // successor is the true successor. + Branch, + + // Switch. Switches over either Int32 or Int64. Uses the SwitchValue class. + Switch, + + // Multiple entrypoints are supported via the EntrySwitch operation. Place this in the root + // block and list the entrypoints as the successors. All blocks backwards-reachable from + // EntrySwitch are duplicated for each entrypoint. + EntrySwitch, + + // Return. Note that B3 procedures don't know their return type, so this can just return any + // type. + Return, + + // This is a terminal that indicates that we will never get here. + Oops +}; + +inline bool isCheckMath(Opcode opcode) +{ + switch (opcode) { + case CheckAdd: + case CheckSub: + case CheckMul: + return true; + default: + return false; + } +} + +std::optional<Opcode> invertedCompare(Opcode, Type); + +inline Opcode constPtrOpcode() +{ + if (is64Bit()) + return Const64; + return Const32; +} + +inline bool isConstant(Opcode opcode) +{ + switch (opcode) { + case Const32: + case Const64: + case ConstDouble: + case ConstFloat: + return true; + default: + return false; + } +} + +inline bool isDefinitelyTerminal(Opcode opcode) +{ + switch (opcode) { + case Jump: + case Branch: + case Switch: + case Oops: + case Return: + return true; + default: + return false; + } +} + +} } // namespace JSC::B3 + +namespace WTF { + +class PrintStream; + +JS_EXPORT_PRIVATE void printInternal(PrintStream&, JSC::B3::Opcode); + +} // namespace WTF + +#endif // ENABLE(B3_JIT) |