text: // Copyright © 2011, Université catholique de Louvain
  // All rights reserved.
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are met:
  //
  // *  Redistributions of source code must retain the above copyright notice,
  //    this list of conditions and the following disclaimer.
  // *  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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT HOLDER 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.
  
  #ifndef MOZART_OPCODES_H
  #define MOZART_OPCODES_H
  
  namespace mozart {
  
  typedef short unsigned int uint16_t;
  
  typedef uint16_t ByteCode;
  typedef ByteCode OpCode;
  
  typedef const ByteCode* ProgramCounter;
  
  const OpCode OpSkip = 0x00;
  
  const OpCode OpMoveXX = 0x01;
  const OpCode OpMoveXY = 0x02;
  const OpCode OpMoveYX = 0x03;
  const OpCode OpMoveYY = 0x04;
  const OpCode OpMoveGX = 0x05;
  const OpCode OpMoveGY = 0x06;
  const OpCode OpMoveKX = 0x07;
  const OpCode OpMoveKY = 0x08;
  
  const OpCode OpMoveMoveXYXY = 0x09;
  const OpCode OpMoveMoveYXYX = 0x0A;
  const OpCode OpMoveMoveYXXY = 0x0B;
  const OpCode OpMoveMoveXYYX = 0x0C;
  
  const OpCode OpAllocateY = 0x0D;
  
  const OpCode OpCreateVarX = 0x0F;
  const OpCode OpCreateVarY = 0x10;
  const OpCode OpCreateVarMoveX = 0x11;
  const OpCode OpCreateVarMoveY = 0x12;
  
  const OpCode OpSetupExceptionHandler = 0x18;
  const OpCode OpPopExceptionHandler = 0x19;
  
  const OpCode OpCallBuiltin0 = 0x20;
  const OpCode OpCallBuiltin1 = 0x21;
  const OpCode OpCallBuiltin2 = 0x22;
  const OpCode OpCallBuiltin3 = 0x23;
  const OpCode OpCallBuiltin4 = 0x24;
  const OpCode OpCallBuiltin5 = 0x25;
  const OpCode OpCallBuiltinN = 0x26;
  
  const OpCode OpCallX = 0x27;
  const OpCode OpCallY = 0x28;
  const OpCode OpCallG = 0x29;
  const OpCode OpCallK = 0x2A;
  const OpCode OpTailCallX = 0x2B;
  const OpCode OpTailCallY = 0x2C;
  const OpCode OpTailCallG = 0x2D;
  const OpCode OpTailCallK = 0x2E;
  
  const OpCode OpSendMsgX = 0x30;
  const OpCode OpSendMsgY = 0x31;
  const OpCode OpSendMsgG = 0x32;
  const OpCode OpSendMsgK = 0x33;
  const OpCode OpTailSendMsgX = 0x34;
  const OpCode OpTailSendMsgY = 0x35;
  const OpCode OpTailSendMsgG = 0x36;
  const OpCode OpTailSendMsgK = 0x37;
  
  const OpCode OpReturn = 0x40;
  const OpCode OpBranch = 0x41;
  const OpCode OpBranchBackward = 0x42;
  const OpCode OpCondBranch = 0x43;
  const OpCode OpCondBranchFB = 0x44;
  const OpCode OpCondBranchBF = 0x45;
  const OpCode OpCondBranchBB = 0x46;
  
  const OpCode OpPatternMatchX = 0x47;
  const OpCode OpPatternMatchY = 0x48;
  const OpCode OpPatternMatchG = 0x49;
  
  const OpCode OpUnifyXX = 0x50;
  const OpCode OpUnifyXY = 0x51;
  const OpCode OpUnifyXG = 0x52;
  const OpCode OpUnifyXK = 0x53;
  const OpCode OpUnifyYY = 0x54;
  const OpCode OpUnifyYG = 0x55;
  const OpCode OpUnifyYK = 0x56;
  const OpCode OpUnifyGG = 0x57;
  const OpCode OpUnifyGK = 0x58;
  const OpCode OpUnifyKK = 0x59;
  
  const OpCode OpCreateStructBase = 0x60;
  static_assert((OpCreateStructBase & 0x1F) == 0,
                "OpCreateStructBase must be aligned on 0x20");
  
  const OpCode OpCreateStructWhatMask = 0x03;
  const OpCode OpCreateStructAbstraction = 0;
  const OpCode OpCreateStructCons = 1;
  const OpCode OpCreateStructTuple = 2;
  const OpCode OpCreateStructRecord = 3;
  
  const OpCode OpCreateStructWhereMask = 0x07 << 2;
  const OpCode OpCreateStructStoreX = 0 << 2;
  const OpCode OpCreateStructStoreY = 1 << 2;
  const OpCode OpCreateStructUnifyX = 2 << 2;
  const OpCode OpCreateStructUnifyY = 3 << 2;
  const OpCode OpCreateStructUnifyG = 4 << 2;
  const OpCode OpCreateStructUnifyK = 5 << 2;
  
  const OpCode OpCreateAbstractionStoreX =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructStoreX;
  const OpCode OpCreateConsStoreX =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructStoreX;
  const OpCode OpCreateTupleStoreX =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructStoreX;
  const OpCode OpCreateRecordStoreX =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructStoreX;
  
  const OpCode OpCreateAbstractionStoreY =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructStoreY;
  const OpCode OpCreateConsStoreY =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructStoreY;
  const OpCode OpCreateTupleStoreY =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructStoreY;
  const OpCode OpCreateRecordStoreY =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructStoreY;
  
  const OpCode OpCreateAbstractionUnifyX =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructUnifyX;
  const OpCode OpCreateConsUnifyX =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructUnifyX;
  const OpCode OpCreateTupleUnifyX =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructUnifyX;
  const OpCode OpCreateRecordUnifyX =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructUnifyX;
  
  const OpCode OpCreateAbstractionUnifyY =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructUnifyY;
  const OpCode OpCreateConsUnifyY =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructUnifyY;
  const OpCode OpCreateTupleUnifyY =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructUnifyY;
  const OpCode OpCreateRecordUnifyY =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructUnifyY;
  
  const OpCode OpCreateAbstractionUnifyG =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructUnifyG;
  const OpCode OpCreateConsUnifyG =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructUnifyG;
  const OpCode OpCreateTupleUnifyG =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructUnifyG;
  const OpCode OpCreateRecordUnifyG =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructUnifyG;
  
  const OpCode OpCreateAbstractionUnifyK =
    OpCreateStructBase | OpCreateStructAbstraction | OpCreateStructUnifyK;
  const OpCode OpCreateConsUnifyK =
    OpCreateStructBase | OpCreateStructCons | OpCreateStructUnifyK;
  const OpCode OpCreateTupleUnifyK =
    OpCreateStructBase | OpCreateStructTuple | OpCreateStructUnifyK;
  const OpCode OpCreateRecordUnifyK =
    OpCreateStructBase | OpCreateStructRecord | OpCreateStructUnifyK;
  
  const OpCode SubOpArrayFillX = 0;
  const OpCode SubOpArrayFillY = 1;
  const OpCode SubOpArrayFillG = 2;
  const OpCode SubOpArrayFillK = 3;
  const OpCode SubOpArrayFillNewVarX = 4;
  const OpCode SubOpArrayFillNewVarY = 5;
  const OpCode SubOpArrayFillNewVars = 6;
  
  // Inlines for some builtins
  const OpCode OpInlineEqualsInteger = 0x80;
  const OpCode OpInlineAdd = 0x81;
  const OpCode OpInlineSubtract = 0x82;
  const OpCode OpInlinePlus1 = 0x83;
  const OpCode OpInlineMinus1 = 0x84;
  
  const OpCode OpInlineGetClass = 0x90;
  
  const OpCode OpDebugEntry = 0xa0;
  const OpCode OpDebugExit = 0xa1;
  const OpCode OpLocalVarname = 0xa2;
  const OpCode OpGlobalVarname = 0xa3;
  const OpCode OpClearY = 0xa4;
  
  }
  
  #endif // MOZART_OPCODES_H
  