| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft Corporation and contributors. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| |
| #if !defined(ASMJS_BYTECODE_WRITER_H) || defined(WASM_BYTECODE_WRITER) |
| |
| #ifndef WASM_BYTECODE_WRITER |
| #define ASMJS_BYTECODE_WRITER_H |
| #define IMP_IWASM |
| #else |
| #define IMP_IWASM virtual |
| #endif |
| |
| #if defined(ASMJS_PLAT) || defined(ENABLE_WASM) |
| namespace Js |
| { |
| struct AsmJsByteCodeWriter : public ByteCodeWriter |
| #ifdef WASM_BYTECODE_WRITER |
| , public IWasmByteCodeWriter |
| #endif |
| { |
| private: |
| using ByteCodeWriter::MarkLabel; |
| |
| public: |
| IMP_IWASM void InitData(ArenaAllocator* alloc, int32 initCodeBufferSize); |
| IMP_IWASM void EmptyAsm(OpCodeAsmJs op); |
| IMP_IWASM void Conv(OpCodeAsmJs op, RegSlot R0, RegSlot R1); |
| IMP_IWASM void AsmInt1Const1(OpCodeAsmJs op, RegSlot R0, int C1); |
| IMP_IWASM void AsmReg1IntConst1(OpCodeAsmJs op, RegSlot R0, int C1); |
| IMP_IWASM void AsmLong1Const1(OpCodeAsmJs op, RegSlot R0, int64 C1); |
| IMP_IWASM void AsmFloat1Const1(OpCodeAsmJs op, RegSlot R0, float C1); |
| IMP_IWASM void AsmDouble1Const1(OpCodeAsmJs op, RegSlot R0, double C1); |
| IMP_IWASM void AsmReg1(OpCodeAsmJs op, RegSlot R0); |
| IMP_IWASM void AsmReg2(OpCodeAsmJs op, RegSlot R0, RegSlot R1); |
| IMP_IWASM void AsmReg3(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2); |
| IMP_IWASM void AsmBr(ByteCodeLabel labelID, OpCodeAsmJs op = OpCodeAsmJs::AsmBr); |
| IMP_IWASM void AsmBrReg1(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1); |
| IMP_IWASM void AsmBrReg1Const1(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1, int C1); |
| IMP_IWASM void AsmStartCall(OpCodeAsmJs op, ArgSlot ArgCount, bool isPatching = false); |
| IMP_IWASM void AsmCall(OpCodeAsmJs op, RegSlot returnValueRegister, RegSlot functionRegister, ArgSlot givenArgCount, AsmJsRetType retType); |
| IMP_IWASM void AsmSlot(OpCodeAsmJs op, RegSlot value, RegSlot instance, int32 slotId); |
| IMP_IWASM void WasmMemAccess(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, uint32 offset, ArrayBufferView::ViewType viewType); |
| |
| IMP_IWASM void MarkAsmJsLabel(ByteCodeLabel labelID); |
| IMP_IWASM uint EnterLoop(ByteCodeLabel loopEntrance); |
| IMP_IWASM void ExitLoop(uint loopId); |
| |
| #ifdef WASM_BYTECODE_WRITER |
| // We don't want to expose api not in IWasmByteCodeWriter, but it's easier to compile them anyway |
| private: |
| #endif |
| void AsmReg4(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3); |
| void AsmReg5(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4); |
| void AsmReg6(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5); |
| void AsmReg7(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6); |
| void AsmReg9(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8); |
| void AsmReg10(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, RegSlot R9); |
| void AsmReg11(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, RegSlot R9, RegSlot R10); |
| void AsmReg17(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16); |
| void AsmReg18(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17); |
| void AsmReg19(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17, RegSlot R18); |
| void AsmBrReg2(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1, RegSlot R2); |
| void AsmTypedArr(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, ArrayBufferView::ViewType viewType); |
| void AsmSimdTypedArr(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, uint8 dataWidth, ArrayBufferView::ViewType viewType); |
| private: |
| void AsmJsUnsigned1(OpCodeAsmJs op, uint C1); |
| template <typename SizePolicy> bool TryWriteAsmReg1(OpCodeAsmJs op, RegSlot R0); |
| template <typename SizePolicy> bool TryWriteAsmReg2(OpCodeAsmJs op, RegSlot R0, RegSlot R1); |
| template <typename SizePolicy> bool TryWriteAsmReg3(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2); |
| template <typename SizePolicy> bool TryWriteAsmReg4(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3); |
| template <typename SizePolicy> bool TryWriteAsmReg5(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4); |
| template <typename SizePolicy> bool TryWriteAsmReg6(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5); |
| template <typename SizePolicy> bool TryWriteAsmReg7(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6); |
| template <typename SizePolicy> bool TryWriteAsmReg9(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8); |
| template <typename SizePolicy> bool TryWriteAsmReg10(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, RegSlot R9); |
| template <typename SizePolicy> bool TryWriteAsmReg11(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10); |
| template <typename SizePolicy> bool TryWriteAsmReg17(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16); |
| template <typename SizePolicy> bool TryWriteAsmReg18(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17); |
| template <typename SizePolicy> bool TryWriteAsmReg19(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, |
| RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17, RegSlot R18); |
| |
| template <typename SizePolicy> bool TryWriteInt1Const1(OpCodeAsmJs op, RegSlot R0, int C1); |
| template <typename SizePolicy> bool TryWriteReg1IntConst1(OpCodeAsmJs op, RegSlot R0, int C1); |
| template <typename SizePolicy> bool TryWriteLong1Const1(OpCodeAsmJs op, RegSlot R0, int64 C1); |
| template <typename SizePolicy> bool TryWriteFloat1Const1(OpCodeAsmJs op, RegSlot R0, float C1); |
| template <typename SizePolicy> bool TryWriteDouble1Const1(OpCodeAsmJs op, RegSlot R0, double C1); |
| template <typename SizePolicy> bool TryWriteAsmBrReg1(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1); |
| template <typename SizePolicy> bool TryWriteAsmBrReg2(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1, RegSlot R2); |
| template <typename SizePolicy> bool TryWriteAsmBrReg1Const1(OpCodeAsmJs op, ByteCodeLabel labelID, RegSlot R1, int C1); |
| template <typename SizePolicy> bool TryWriteAsmCall(OpCodeAsmJs op, RegSlot returnValueRegister, RegSlot functionRegister, ArgSlot givenArgCount, AsmJsRetType retType); |
| template <typename SizePolicy> bool TryWriteAsmSlot(OpCodeAsmJs op, RegSlot value, RegSlot instance, int32 slotId); |
| template <typename SizePolicy> bool TryWriteWasmMemAccess(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, uint32 offset, ArrayBufferView::ViewType viewType); |
| template <typename SizePolicy> bool TryWriteAsmTypedArr(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, ArrayBufferView::ViewType viewType); |
| template <typename SizePolicy> bool TryWriteAsmSimdTypedArr(OpCodeAsmJs op, RegSlot value, uint32 slotIndex, uint8 dataWidth, ArrayBufferView::ViewType viewType); |
| template <typename SizePolicy> bool TryWriteAsmJsUnsigned1(OpCodeAsmJs op, uint C1); |
| |
| void AddJumpOffset(Js::OpCodeAsmJs op, ByteCodeLabel labelId, uint fieldByteOffset); |
| |
| #ifdef WASM_BYTECODE_WRITER |
| // WebAssembly only write functions |
| public: |
| // IWasmByteCodeWriter Implementation |
| virtual void Create() override; |
| virtual void Begin(FunctionBody* functionWrite, ArenaAllocator* alloc) override; |
| virtual void End() override; |
| virtual void Reset() override; |
| virtual ByteCodeLabel DefineLabel() override; |
| #endif |
| }; |
| } |
| |
| #undef IMP_IWASM |
| #endif |
| |
| #endif |