blob: 59a61539adb3b7484f871aea0d18e9eb7f6d982d [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
****************************************************************************
*
* File: ExpPCodeInstruction.h
* Description: PCODE opcode list (compiler and executor) and classes and
* enums for compiling clauses to PCODE.
* Created: 8/25/97
* Language: C++
*
*
*
****************************************************************************
*/
#ifndef ExpPCodeInstruction_h
#define ExpPCodeInstruction_h
#include "NAStdlib.h"
// Forward internal declaractions
//
class PCIType;
class PCIAddressingModeList;
class PCIOperandList;
class PCodeInstruction;
// RMI reduction typedef's
//
typedef PCIType PCIT;
typedef PCIAddressingModeList AML;
typedef PCIOperandList OL;
typedef PCodeInstruction PCI;
typedef Int64 PCIID;
// PCode Binary (formally referred as code) remains to be 32-bit long on
// 64-bit platform but when it contains pointers/addresses it takes two
// consecutive storge space. The same applies to the operand list as Operand
// is also a 32-bit value.
// As result some PCode instructions (PCI) would have longer PCodeBinary
// sequences and operand lists. During PCode walk through in optimization,
// address fixup, and execution, extra pointer adjustment would be needed
// for PCode instructions involving address/pointer operands.
typedef Int32 PCodeBinary;
// Pointers in PCodeBinary stream can take 1 or 2 entries
// Currently 1 on 32-bit platform and 2 on 64-bit platform
#define PCODEBINARIES_PER_PTR sizeof(char*)/sizeof(PCodeBinary)
// PCIType
//
// The PCIType class encapsulates and provides a uniform name space
// for enumerations related to PCode (and nothing more). PCIType contains
// the Operation, AddressingMode, and Instruction enumerations and
// static member functions for converting these enumerations to strings
// for display.
//
class PCIType {
public:
// PCode operations -- These enumerations represent the different PCode
// operations. These are NOT the actual byte codes that are
// executed. A PCode operation in conjunction with one or more
// addressing modes and operands maps to one or more byte codes
// that are interpreted when a expression is executed. Different PCode
// operations may map to the same byte codes (i.e. Op_LD_CONSTANT
// and Op_LD_TEMPORARY).
//
enum Operation {
Op_OPDATA,
// Moves and conversions
Op_MOVE,
// Nulls
Op_NULL, Op_NOT_NULL_BRANCH, Op_NOT_NULL_BRANCH_COMP, Op_NULL_BITMAP, Op_NOT_NULL_BITMAP_BRANCH,
Op_NULL_VIOLATION, Op_REPLACE_NULL, Op_NULL_BYTES,
// Relational operators
Op_EQ, Op_LT, Op_GT, Op_LE, Op_GE, Op_NE, Op_COMP, Op_ZERO, Op_NOTZERO,
// Logical operators
Op_AND, Op_OR,
// Arithematic operators
Op_ADD, Op_SUB, Op_MUL, Op_DIV, Op_DIV_ROUND, Op_SUM, Op_MOD, Op_NEG,
Op_MINMAX,
// Bitwise operator
Op_BITOR,
// Hash value combination operator
Op_HASHCOMB,
// Encoding/decoding operators
Op_ENCODE,
Op_DECODE,
// Hash function
Op_HASH,
// new hash function
Op_HASH2_DISTRIB,
// Generic functions. Actual function name(OperTypeEnum) will be stored
// as part of the generated pcode.
// Number and type of operands will depend on OperTypeEnum.
Op_GENFUNC,
// Fill memory
Op_FILL_MEM_BYTES,
// Return function
Op_RETURN,
// Branching
Op_BRANCH, Op_TARGET, Op_BRANCH_AND, Op_BRANCH_OR,
// Error handling
Op_RANGE_LOW, Op_RANGE_HIGH,
// Evaluating clauses
Op_CLAUSE, Op_CLAUSE_EVAL, Op_CLAUSE_BRANCH,
// Miscellaneous
Op_PROFILE,
Op_UPDATE_ROWLEN, Op_UPDATE_ROWLEN2, Op_UPDATE_ROWLEN3,
Op_OFFSET,
Op_HDR, // clause header pcode
Op_NULLIFZERO,
Op_COPYVARROW,
// source points to an 8 byte varchar value which is the ptr to data.
// Length of source contains the length of data.
Op_CONV_VC_PTR,
Op_NOP, Op_END
};
// PCode Addressing Modes -- These enumerations represent the different
// PCode addressing modes. There are four different types of operands:
// integer, signed integer, unsigned integer and pointer; and three sizes:
// 64, 32, and 16 bit. The integer modes are used for operations that
// are ignorant of the sign of the operand (i.e. BIT_XOR). Either
// signed integer or unsigned integer modes are used for operations that
// do depend on the sign of the operand (i.e. ADD).
//
enum AddressingMode {
// None
//
AM_NONE,
// Memory accesses
//
MBIN8, MBIN8U, MBIN8S, MBIN16U, MBIN16S, MBIN32U, MBIN32S,
MBIN64S, MBIN64U, MPTR32,
MASCII, MDECS, MDECU, MFLT32, MFLT64, MATTR3, MATTR4, MATTR5, MATTR6,
MBIGU, MBIGS, MUNI, MUNIV,
// Immediate accesses
IBIN8U, IBIN16U, IBIN32S, IBIN64S, IATTR4, IATTR3, IATTR2, IPTR
};
// PCode Instructions -- These enumerations represent the actual byte
// codes that are interpreted when an expression is executed.
// NOTE: These byte codes are stored in modules, don't rearrange
// the existing numbers. Add new numbers at the end.
enum Instruction {
// OP data vector
OPDATA_MPTR32_IBIN32S = 0,
OPDATA_MBIN16U_IBIN32S = 1,
// Moves and conversions
MOVE_MBIN32S = 2,
MOVE_MBIN32S_IBIN32S = 3,
MOVE_MBIN8_MBIN8_IBIN32S = 4,
MOVE_MBIN32U_MBIN16U = 5,
MOVE_MBIN32S_MBIN16U = 6,
MOVE_MBIN64S_MBIN16U = 7,
MOVE_MBIN32U_MBIN16S = 8,
MOVE_MBIN32S_MBIN16S = 9,
MOVE_MBIN64S_MBIN16S = 10,
MOVE_MBIN64S_MBIN32U = 11,
MOVE_MBIN64S_MBIN32S = 12,
MOVE_MBIN64S_MDECS_IBIN32S = 13,
MOVE_MBIN64S_MDECU_IBIN32S = 14,
// Nulls
NULL_MBIN16U = 16,
NULL_MBIN16U_IBIN16U = 17,
NULL_TEST_MBIN32S_MBIN16U_IBIN32S = 18,
NOT_NULL_BRANCH_MBIN16S_MBIN16S_IBIN32S = 19,
NOT_NULL_BRANCH_MBIN16S_MBIN16S_MBIN16S_IBIN32S = 20,
NULL_VIOLATION_MBIN16U = 21,
NULL_VIOLATION_MBIN16U_MBIN16U = 22,
INSTRUCTION_FILLER_23 = 23,
INSTRUCTION_FILLER_24 = 24,
INSTRUCTION_FILLER_25 = 25,
INSTRUCTION_FILLER_26 = 26,
INSTRUCTION_FILLER_27 = 27,
ZERO_MBIN32S_MBIN32U = 31,
NOTZERO_MBIN32S_MBIN32U = 32,
// Relational operations
EQ_MBIN32S_MBIN16S_MBIN16S = 33,
EQ_MBIN32S_MBIN16S_MBIN32S = 34,
INSTRUCTION_FILLER_35 = 35,
EQ_MBIN32S_MBIN32S_MBIN32S = 36,
EQ_MBIN32S_MBIN16U_MBIN16U = 37,
EQ_MBIN32S_MBIN16U_MBIN32U = 38,
INSTRUCTION_FILLER_39 = 39,
EQ_MBIN32S_MBIN32U_MBIN32U = 40,
EQ_MBIN32S_MBIN16S_MBIN32U = 41,
INSTRUCTION_FILLER_42 = 42,
LT_MBIN32S_MBIN16S_MBIN16S = 43,
LT_MBIN32S_MBIN16S_MBIN32S = 44,
INSTRUCTION_FILLER_45 = 45,
LT_MBIN32S_MBIN32S_MBIN32S = 46,
LT_MBIN32S_MBIN16U_MBIN16U = 47,
LT_MBIN32S_MBIN16U_MBIN32U = 48,
INSTRUCTION_FILLER_49 = 49,
LT_MBIN32S_MBIN32U_MBIN32U = 50,
LT_MBIN32S_MBIN16S_MBIN32U = 51,
INSTRUCTION_FILLER_52 = 52,
GT_MBIN32S_MBIN16S_MBIN16S = 53,
GT_MBIN32S_MBIN16S_MBIN32S = 54,
INSTRUCTION_FILLER_55 = 55,
GT_MBIN32S_MBIN32S_MBIN32S = 56,
GT_MBIN32S_MBIN16U_MBIN16U = 57,
GT_MBIN32S_MBIN16U_MBIN32U = 58,
INSTRUCTION_FILLER_59 = 59,
GT_MBIN32S_MBIN32U_MBIN32U = 60,
GT_MBIN32S_MBIN16S_MBIN32U = 61,
INSTRUCTION_FILLER_62 = 62,
// Boolean operations
AND_MBIN32S_MBIN32S_MBIN32S = 63,
OR_MBIN32S_MBIN32S_MBIN32S = 64,
// Arithematic operations
ADD_MBIN16S_MBIN16S_MBIN16S = 65,
ADD_MBIN32S_MBIN32S_MBIN32S = 66,
ADD_MBIN64S_MBIN64S_MBIN64S = 67,
SUB_MBIN16S_MBIN16S_MBIN16S = 68,
SUB_MBIN32S_MBIN32S_MBIN32S = 69,
SUB_MBIN64S_MBIN64S_MBIN64S = 70,
MUL_MBIN16S_MBIN16S_MBIN16S = 71,
MUL_MBIN32S_MBIN32S_MBIN32S = 72,
MUL_MBIN64S_MBIN64S_MBIN64S = 73,
SUM_MBIN32S_MBIN32S = 77,
INSTRUCTION_FILLER_78 = 78,
SUM_MBIN64S_MBIN64S = 79,
INSTRUCTION_FILLER_80 = 80,
MOD_MBIN32S_MBIN32S_MBIN32S = 83,
MINMAX_MBIN8_MBIN8_MBIN32S_IBIN32S = 84,
// Encoding operations
ENCODE_MASCII_MBIN16S_IBIN32S = 87,
ENCODE_MASCII_MBIN16U_IBIN32S = 88,
ENCODE_MASCII_MBIN32S_IBIN32S = 89,
ENCODE_MASCII_MBIN32U_IBIN32S = 90,
ENCODE_MASCII_MBIN64S_IBIN32S = 91,
ENCODE_DATETIME = 92,
ENCODE_NXX = 93,
// Hash functions
HASH_MBIN32U_MPTR32_IBIN32S_IBIN32S = 94,
// Branch
BRANCH = 95,
BRANCH_I32 = 96,
// Errors
RANGE_LOW_S32S64 = 97,
RANGE_HIGH_S32S64 = 98,
RANGE_LOW_U32S64 = 99,
RANGE_HIGH_U32S64 = 100,
RANGE_LOW_S64S64 = 101,
RANGE_HIGH_S64S64 = 102,
RANGE_LOW_S16S64 = 103,
RANGE_HIGH_S16S64 = 104,
RANGE_LOW_U16S64 = 105,
RANGE_HIGH_U16S64 = 106,
// Miscellaneous
CLAUSE = 107,
CLAUSE_EVAL = 108,
CLAUSE_BRANCH = 109,
PROFILE = 110,
NULL_VIOLATION = 111,
UPDATE_ROWLEN = 112,
NOP = 113,
// End
END = 114,
// Fill memory
FILL_MEM_BYTES = 115,
MOVE_MBIN16U_IBIN16U = 116,
EQ_MBIN32S_MASCII_MASCII = 117,
// PCode instructions added after SQL/MX FCS:
// arith pcode instructions.
ADD_MBIN32S_MBIN16S_MBIN16S = 118,
ADD_MBIN32S_MBIN16S_MBIN32S = 119,
INSTRUCTION_FILLER_120 = 120,
ADD_MBIN64S_MBIN32S_MBIN64S = 121,
INSTRUCTION_FILLER_121 = 122,
SUB_MBIN32S_MBIN16S_MBIN16S = 123,
SUB_MBIN32S_MBIN16S_MBIN32S = 124,
SUB_MBIN32S_MBIN32S_MBIN16S = 125,
MUL_MBIN32S_MBIN16S_MBIN16S = 126,
MUL_MBIN32S_MBIN16S_MBIN32S = 127,
INSTRUCTION_FILLER_128 = 128,
DIV_MBIN64S_MBIN64S_MBIN64S = 129,
LT_MBIN32S_MASCII_MASCII = 130,
LE_MBIN32S_MASCII_MASCII = 131,
GT_MBIN32S_MASCII_MASCII = 132,
GE_MBIN32S_MASCII_MASCII = 133,
LE_MBIN32S_MBIN16S_MBIN16S = 134,
LE_MBIN32S_MBIN16S_MBIN32S = 135,
INSTRUCTION_FILLER_136 = 136,
LE_MBIN32S_MBIN32S_MBIN32S = 137,
LE_MBIN32S_MBIN16U_MBIN16U = 138,
LE_MBIN32S_MBIN16U_MBIN32U = 139,
INSTRUCTION_FILLER_140 = 140,
LE_MBIN32S_MBIN32U_MBIN32U = 141,
LE_MBIN32S_MBIN16S_MBIN32U = 142,
INSTRUCTION_FILLER_143 = 143,
GE_MBIN32S_MBIN16S_MBIN16S = 144,
GE_MBIN32S_MBIN16S_MBIN32S = 145,
INSTRUCTION_FILLER_146 = 146,
GE_MBIN32S_MBIN32S_MBIN32S = 147,
GE_MBIN32S_MBIN16U_MBIN16U = 148,
GE_MBIN32S_MBIN16U_MBIN32U = 149,
INSTRUCTION_FILLER_150 = 150,
GE_MBIN32S_MBIN32U_MBIN32U = 151,
GE_MBIN32S_MBIN16S_MBIN32U = 152,
INSTRUCTION_FILLER_153 = 153,
INSTRUCTION_FILLER_154 = 154,
INSTRUCTION_FILLER_155 = 155,
// Hash value combination operation
HASHCOMB_MBIN32U_MBIN32U_MBIN32U = 156,
EQ_MBIN32S_MBIN16U_MBIN16S = 157,
LT_MBIN32S_MBIN16U_MBIN16S = 158,
LE_MBIN32S_MBIN16U_MBIN16S = 159,
GT_MBIN32S_MBIN16U_MBIN16S = 160,
GE_MBIN32S_MBIN16U_MBIN16S = 161,
EQ_MBIN32S_MBIN64S_MBIN64S = 162,
LT_MBIN32S_MBIN64S_MBIN64S = 163,
LE_MBIN32S_MBIN64S_MBIN64S = 164,
GT_MBIN32S_MBIN64S_MBIN64S = 165,
GE_MBIN32S_MBIN64S_MBIN64S = 166,
NE_MBIN32S_MBIN64S_MBIN64S = 167,
// short circuit branch instructions
BRANCH_AND = 168,
BRANCH_OR = 169,
// Hash functions
HASH_MBIN32U_MBIN32_IBIN32S_IBIN32S = 170,
HASH_MBIN32U_MBIN16_IBIN32S_IBIN32S = 171,
//HASH_MBIN32U_MPTR32_IBIN32S_IBIN32S = 172,
HASH_MBIN32U_MBIN64_IBIN32S_IBIN32S = 173,
ENCODE_DECS = 176,
GENFUNC_PCODE_1 = 181,
INSTRUCTION_FILLER_182 = 182,
MUL_MBIN64S_MBIN16S_MBIN32S = 183,
MUL_MBIN64S_MBIN32S_MBIN32S = 184,
INSTRUCTION_FILLER_185 = 185,
MOD_MBIN32U_MBIN32U_MBIN32S = 186,
NOT_NULL_BRANCH_MBIN32S_MBIN16S_MBIN16S_IBIN32S = 187,
NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S = 188,
NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S_IBIN32S = 189,
NOT_NULL_BRANCH_MBIN16S_IBIN32S = 190,
GENFUNC_MBIN8_MBIN8_MBIN8_IBIN32S_IBIN32S = 191,
INSTRUCTION_FILLER_192 = 192,
MOVE_MFLT64_MBIN16S = 193,
MOVE_MFLT64_MFLT32 = 194,
INSTRUCTION_FILLER_195 = 195,
NE_MBIN32S_MBIN16S_MBIN16S = 196,
INSTRUCTION_FILLER_197 = 197,
INSTRUCTION_FILLER_198 = 198,
INSTRUCTION_FILLER_199 = 199,
// Standard move instructions
MOVE_MBIN8_MBIN8 = 200,
MOVE_MBIN16U_MBIN16U = 201,
MOVE_MBIN32U_MBIN32U = 202,
MOVE_MBIN64S_MBIN64S = 203,
ADD_MFLT64_MFLT64_MFLT64 = 204,
SUB_MFLT64_MFLT64_MFLT64 = 205,
MUL_MFLT64_MFLT64_MFLT64 = 206,
DIV_MFLT64_MFLT64_MFLT64 = 207,
INSTRUCTION_FILLER_208 = 208,
SUM_MFLT64_MFLT64 = 209,
RANGE_MFLT64 = 210,
// IEEE float comparisons
NE_MBIN32S_MFLT64_MFLT64 = 211,
NE_MBIN32S_MFLT32_MFLT32 = 212,
GT_MBIN32S_MFLT64_MFLT64 = 213,
GT_MBIN32S_MFLT32_MFLT32 = 214,
GE_MBIN32S_MFLT64_MFLT64 = 215,
GE_MBIN32S_MFLT32_MFLT32 = 216,
EQ_MBIN32S_MFLT64_MFLT64 = 217,
EQ_MBIN32S_MFLT32_MFLT32 = 218,
LE_MBIN32S_MFLT64_MFLT64 = 219,
LE_MBIN32S_MFLT32_MFLT32 = 220,
LT_MBIN32S_MFLT64_MFLT64 = 221,
LT_MBIN32S_MFLT32_MFLT32 = 222,
HASH2_DISTRIB = 223,
// To support the aligned record format.
NULL_BITMAP = 224, // main null bitmap manipulation
NULL_BITMAP_SET = 225, // subcode to set a null bit
NULL_BITMAP_CLEAR = 226, // subcode to clear a null bit
NULL_BITMAP_TEST = 227, // subcode to test a null bit
OPDATA_MPTR32_IBIN32S_IBIN32S = 228,
NULL_TEST_BIT_MBIN32S_MBIN32S_IBIN32S = 229,
NNBB_MPTR32_IBIN16S_IBIN32S = 230,
OPDATA_MATTR5_IBIN32S = 231,
INSTRUCTION_FILLER_232 = 232,
INSTRUCTION_FILLER_233 = 233,
INSTRUCTION_FILLER_234 = 234,
INSTRUCTION_FILLER_235 = 235,
INSTRUCTION_FILLER_236 = 236,
DIV_MBIN64S_MBIN64S_MBIN64S_ROUND = 237,
NULL_VIOLATION_MPTR32_MPTR32_IPTR_IPTR = 238,
// added IPTR_ for pointer to function GetHistoryRowOLAP.
// note that the indexes are different on 64-bit mode
// pCode[0] will contain pointer to the function,
// pCode[1] will point to Tcb to get to the history buffer
// pCode[2] , pCode[3] --index (MBIN32S)/
// pCode[4] pCode[5] -- result
// pCode[6] pCode[7] -- source
OFFSET_IPTR_IPTR_MBIN32S_MBIN64S_MBIN64S = 239,
// pCode[0] will contain pointer to the function,
// pCode[1] will point to Tcb to get to the history buffer
// pCode[2] --index (IBIN32S)/
// pCode[3] pCode[4] -- result
// pCode[5] pCode[6] -- source
OFFSET_IPTR_IPTR_IBIN32S_MBIN64S_MBIN64S = 240,
ADD_MBIGS_MBIGS_MBIGS_IBIN32S = 241,
SUB_MBIGS_MBIGS_MBIGS_IBIN32S = 242,
MUL_MBIGS_MBIGS_MBIGS_IBIN32S = 243,
MOVE_MBIGS_MBIGS_IBIN32S_IBIN32S = 244,
MOVE_MBIGS_MBIN64S_IBIN32S = 245,
MOVE_MBIN64S_MBIGS_IBIN32S = 246,
// null branch processing for indirect varchars
NOT_NULL_BRANCH_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S = 247,
NOT_NULL_BRANCH_MBIN32S_MBIN32S_IATTR3_IBIN32S = 248,
NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S = 249,
NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_IATTR3_IBIN32S = 250,
// move for fixed char
MOVE_MASCII_MASCII_IBIN32S_IBIN32S = 251,
INSTRUCTION_FILLER_252 = 252,
INSTRUCTION_FILLER_253 = 253,
INSTRUCTION_FILLER_254 = 254,
INSTRUCTION_FILLER_255 = 255,
INSTRUCTION_FILLER_256 = 256,
INSTRUCTION_FILLER_257 = 257,
INSTRUCTION_FILLER_258 = 258,
INSTRUCTION_FILLER_259 = 259,
INSTRUCTION_FILLER_260 = 260,
INSTRUCTION_FILLER_261 = 261,
// null test
NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S = 262,
NE_MBIN32S_MASCII_MASCII = 263,
RETURN = 264,
RETURN_IBIN32S = 265,
HASHCOMB_BULK_MBIN32U = 266,
NOT_NULL_BRANCH_BULK = 267,
MOVE_BULK = 268,
NULL_BITMAP_BULK = 269,
COMP_MBIN32S_MBIGS_MBIGS_IBIN32S_IBIN32S = 270,
SUM_MBIN64S_MBIN32S = 271,
INSTRUCTION_FILLER_272 = 272,
// short circuit counted branch instructions
BRANCH_AND_CNT = 273,
BRANCH_OR_CNT = 274,
// Comparison for fixed
COMP_MBIN32S_MASCII_MASCII_IBIN32S_IBIN32S_IBIN32S = 275,
INSTRUCTION_FILLER_276 = 276,
INSTRUCTION_FILLER_277 = 277,
INSTRUCTION_FILLER_278 = 278,
INSTRUCTION_FILLER_279 = 279,
// Unicode support
COMP_MBIN32S_MATTR4_MATTR4_IBIN32S_IBIN32S_IBIN32S = 280,
COMP_MBIN32S_MUNI_MUNI_IBIN32S_IBIN32S_IBIN32S = 281,
MOVE_MUNI_MUNI_IBIN32S_IBIN32S = 282,
HASH_MBIN32U_MATTR4_IBIN32S = 283,
// Varchar support
MOVE_MATTR5_MATTR5 = 284,
COMP_MBIN32S_MATTR5_MATTR5_IBIN32S = 285,
HASH_MBIN32U_MATTR5 = 286,
SUBSTR_MATTR5_MATTR5_MBIN32S_MBIN32S = 287,
GENFUNC_MATTR5_MATTR5_IBIN32S = 288,
// Bignum support
MOVE_MBIGS_MBIN32S_IBIN32S = 289,
MOVE_MBIGS_MBIN16S_IBIN32S = 290,
SUM_MBIN16U_MBIN16U_MBIGS_MBIN64S = 291,
SUM_MBIN16U_MBIN16U_MBIGS_MBIGS = 292,
// Varchar Unicode support
COMP_MBIN32S_MUNIV_MUNIV_IBIN32S = 293,
HASH_MBIN32U_MUNIV = 294,
// Moves
MOVE_MFLT64_MBIN32S = 295,
MOVE_MFLT64_MBIN64S = 296,
// String length functions
STRLEN_MBIN32U_MATTR5 = 297,
STRLEN_MBIN32U_MUNIV = 298,
// Other string functions
GENFUNC_MATTR5_MATTR5_MBIN32S_IBIN32S = 299,
POS_MBIN32S_MATTR5_MATTR5 = 300,
LIKE_MBIN32S_MATTR5_MATTR5_IBIN32S_IBIN32S = 301,
MOVE_MBIN16U_MBIN8 = 302,
// Header clause instruction used when writing
// a data record in disk format(both Packed & Aligned).
HDR_MPTR32_IBIN32S_IBIN32S_IBIN32S_IBIN32S_IBIN32S = 303,
NNB_SPECIAL_NULLS_MBIN32S_MATTR3_MATTR3_IBIN32S_IBIN32S = 304,
NULLIFZERO_MPTR32_MATTR3_MPTR32_IBIN32S = 305,
NNB_MATTR3_IBIN32S = 306,
// null helper for hash
NNB_MBIN32S_MATTR3_IBIN32S_IBIN32S = 307,
REPLACE_NULL_MATTR3_MBIN32S = 308,
REPLACE_NULL_MATTR3_MBIN32U = 309,
REPLACE_NULL_MATTR3_MBIN16S = 310,
REPLACE_NULL_MATTR3_MBIN16U = 311,
SUM_MATTR3_MATTR3_IBIN32S_MBIN32S_MBIN32S = 312,
SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN64S = 313,
SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN32S = 314,
SUM_MATTR3_MATTR3_IBIN32S_MFLT64_MFLT64 = 315,
UPDATE_ROWLEN3_MATTR5_IBIN32S = 316,
FILL_MEM_BYTES_VARIABLE = 317,
// move for fixed/varchars
MOVE_MASCII_MATTR5_IBIN32S = 318,
MOVE_MATTR5_MASCII_IBIN32S = 319,
// Indirect branch related instructions
SWITCH_MBIN32S_MATTR5_MPTR32_IBIN32S_IBIN32S = 320,
SWITCH_MBIN32S_MBIN64S_MPTR32_IBIN32S_IBIN32S = 321,
BRANCH_INDIRECT_MBIN32S = 322,
CONCAT_MATTR5_MATTR5_MATTR5 = 323,
SUM_MATTR3_MATTR3_IBIN32S_MBIGS_MBIGS_IBIN32S = 324,
NULL_BYTES = 325,
// COPYVARROW_MBIN8_MBIN8_IBIN32S_IBIN32S_IBIN32S_IBIN32S
// pCode[0], pCode[1] --result
// pCode[2], pCode[3] -- source
// pCode[4] --lastVoaOffset
// pcode[5] --lastVCIndicatorLength
// pCode[6] --lastNULLIndicatorLength
// pCode[7] --row length
COPYVARROW_MBIN8_MBIN8_IBIN32S_IBIN32S_IBIN32S_IBIN32S = 326,
CONVVCPTR_MBIN32S_MATTR5_IBIN32S = 327,
CONVVCPTR_MFLT32_MATTR5_IBIN32S = 328,
CONVVCPTR_MATTR5_MATTR5 = 329,
CONVVCPTR_MBIN64S_MATTR5_IBIN32S = 330,
// Decoding operations
DECODE_MASCII_MBIN16S_IBIN32S = 331,
DECODE_MASCII_MBIN16U_IBIN32S = 332,
DECODE_MASCII_MBIN32S_IBIN32S = 333,
DECODE_MASCII_MBIN32U_IBIN32S = 334,
DECODE_MASCII_MBIN64S_IBIN32S = 335,
DECODE_DATETIME = 336,
DECODE_NXX = 337,
DECODE_DECS = 338,
// unary operations
NEGATE_MASCII_MASCII = 339,
// tinyint operations
ENCODE_MASCII_MBIN8S_IBIN32S = 340,
ENCODE_MASCII_MBIN8U_IBIN32S = 341,
DECODE_MASCII_MBIN8S_IBIN32S = 342,
DECODE_MASCII_MBIN8U_IBIN32S = 343,
MOVE_MBIN16S_MBIN8S = 344,
MOVE_MBIN16U_MBIN8U = 345,
MOVE_MBIN32S_MBIN8S = 346,
MOVE_MBIN32U_MBIN8U = 347,
MOVE_MBIN64S_MBIN8S = 348,
MOVE_MBIN64U_MBIN8U = 349,
EQ_MBIN32S_MBIN8S_MBIN8S = 350,
NE_MBIN32S_MBIN8S_MBIN8S = 351,
LT_MBIN32S_MBIN8S_MBIN8S = 352,
GT_MBIN32S_MBIN8S_MBIN8S = 353,
LE_MBIN32S_MBIN8S_MBIN8S = 354,
GE_MBIN32S_MBIN8S_MBIN8S = 355,
EQ_MBIN32S_MBIN8U_MBIN8U = 356,
NE_MBIN32S_MBIN8U_MBIN8U = 357,
LT_MBIN32S_MBIN8U_MBIN8U = 358,
GT_MBIN32S_MBIN8U_MBIN8U = 359,
LE_MBIN32S_MBIN8U_MBIN8U = 360,
GE_MBIN32S_MBIN8U_MBIN8U = 361,
// largeint unsigned operations
MOVE_MBIN64S_MBIN64U = 362,
MOVE_MBIN64U_MBIN64S = 363,
MOVE_MBIN64U_MBIN64U = 364,
RANGE_LOW_S8S64 = 365,
RANGE_HIGH_S8S64 = 366,
RANGE_LOW_U8S64 = 367,
RANGE_HIGH_U8S64 = 368,
MOVE_MBIN8S_MBIN16S = 369,
MOVE_MBIN8U_MBIN16U = 370,
MOVE_MBIN8U_MBIN16S = 371,
MOVE_MBIN8S_MBIN16U = 372,
//***************************************************************
// Add new PCODE instructions immediately above this comment!!!!!
//***************************************************************
// this should have the highest number of the PCODE instructions
LAST_PCODE_INSTR
};
// Following enum is needed by Native Expressions code to resolve
// an ambiguity with an LLVM object that is also named Instruction.
typedef enum Instruction enum_PCI ;
// 64-bit - see notes above at PCodeBinary define.
typedef Int32 Operand;
static PCIType::AddressingMode getMemoryAddressingMode(Int32 datatype);
static Int32 isMemoryAddressingMode(PCIType::AddressingMode am);
static Int32 getNumberOperandsForAddressingMode(PCIType::AddressingMode am);
static Int32 getOperandLengthForAddressingMode(PCIType::AddressingMode am);
static Int16 getDataTypeForMemoryAddressingMode(PCIType::AddressingMode am);
// Helper functions for displaying the enumerations
//
static const char *operationString(PCIType::Operation op);
static const char *addressingModeString(PCIType::AddressingMode am);
//buf should be 32 bytes
static void operandString(Int32 operand, char* buf);
static char *instructionString(PCIType::Instruction instr);
};
// PCIAddressingModeList (AML for short)
//
// The AML class is a container class for a set of 0 to 3 addressing modes.
// A convenient constructor is provided for creating an AML with
// up to 3 addressing modes. Accessors for querying the number and modes
// are provided. Once an AML is created, the entries are read-only.
//
// An independent class for a set of addressing modes is used (rather than
// a generic container) for a couple of reasons. Since this code runs at
// execution time (possibly in EID), no standard containers (i.e. RW) can
// be used. Instead of writing a generic template container, I
// chose to implement the simple AML and OL classes. This also allows simpler
// code and better type checking since the AML and OL classes are geared
// with convenient constructors and robust type checking.
//
// The AML and OL classes are only meant to be used to simply argument
// passing to the PCI constructors. Nothing more.
//
class PCIAddressingModeList {
public:
// Constructor
//
PCIAddressingModeList(PCIType::AddressingMode am1 =PCIType::AM_NONE,
PCIType::AddressingMode am2 =PCIType::AM_NONE,
PCIType::AddressingMode am3 =PCIType::AM_NONE,
PCIType::AddressingMode am4 =PCIType::AM_NONE,
PCIType::AddressingMode am5 =PCIType::AM_NONE,
PCIType::AddressingMode am6 =PCIType::AM_NONE) {
numberAddressingModes_ = 0;
if(am1 != PCIType::AM_NONE) numberAddressingModes_++;
if(am2 != PCIType::AM_NONE) numberAddressingModes_++;
if(am3 != PCIType::AM_NONE) numberAddressingModes_++;
if(am4 != PCIType::AM_NONE) numberAddressingModes_++;
if(am5 != PCIType::AM_NONE) numberAddressingModes_++;
if(am6 != PCIType::AM_NONE) numberAddressingModes_++;
addressingMode_[0] = am1;
addressingMode_[1] = am2;
addressingMode_[2] = am3;
addressingMode_[3] = am4;
addressingMode_[4] = am5;
addressingMode_[5] = am6;
};
// Accessors
//
Int32 getNumberAddressingModes() const { return numberAddressingModes_; };
PCIType::AddressingMode getAddressingMode(Int32 mode) const
{ return addressingMode_[mode]; };
private:
// numberAddressingMode_ - Indicates the number of addressing modes that
// are valid (0-6). Is set automatically by the constructor and is
// read-only otherwise. Can be queried with the getNumberAddressingModes()
// method.
//
Int32 numberAddressingModes_;
// addressingMode_ - A vector of the addressing modes. Is set automatically
// by the constructor and is read-only otherwise. Can be queried with the
// getAddressingMode() accessor.
//
PCIType::AddressingMode addressingMode_[6];
};
// PCIOperandList (OL for short)
//
// The OL class is a container class for a set of 0 to 20 operands.
// Convenient constructors are provided for creating an OL with up to
// 9 operands. Accessors for querying the number and operands are provided.
// Once an OL is created, the entries are read-only.
//
// See PCIAddressingMode comments above.
//
class PCIOperandList {
public:
// Constructors
//
PCIOperandList() { initList(0); };
PCIOperandList(PCIType::Operand arg1) { initList(1, arg1); };
PCIOperandList(Int64 arg1) {
numberOperands_ = 2;
*((Int64*)operand_) = arg1;
};
PCIOperandList(Int64 arg1, PCIType::Operand arg2) {
numberOperands_ = 3;
*((Int64*)&operand_[0]) = arg1;
operand_[2] = arg2;
};
PCIOperandList(Int64 arg1, Int64 arg2) {
numberOperands_ = 4;
*((Int64*)&operand_[0]) = arg1;
*((Int64*)&operand_[2]) = arg2;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2) { initList(2, arg1, arg2); };
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3) {
initList(3, arg1, arg2, arg3);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, Int32 arg4) {
initList(4, arg1, arg2, arg3, arg4);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, Int64 arg4) {
initList(5, arg1, arg2, arg3, 0, 0);
numberOperands_ = 5;
*((Int64*)&operand_[3]) = arg4;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5)
{
initList(5, arg1, arg2, arg3, arg4, arg5);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6) {
initList(6, arg1, arg2, arg3, arg4, arg5, arg6);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7) {
initList(7, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
};
PCIOperandList(Int64 arg1, Int64 arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8) {
numberOperands_ = 10;
*((Int64*)&operand_[0]) = arg1; *((Int64*)&operand_[2]) = arg2;
operand_[4] = arg3; operand_[5] = arg4; operand_[6] = arg5;
operand_[7] = arg6; operand_[8] = arg7; operand_[9] = arg8;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, Int64 arg7, Int64 arg8) {
numberOperands_ = 10;
operand_[0] = arg1; operand_[1] = arg2; operand_[2] = arg3;
operand_[3] = arg4; operand_[4] = arg5; operand_[5] = arg6;
*((Int64*)&operand_[6]) = arg7; *((Int64*)&operand_[8]) = arg8;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8) {
initList(8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
};
PCIOperandList(Int64 arg1, Int64 arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9) {
numberOperands_ = 11;
*((Int64*)&operand_[0]) = arg1; *((Int64*)&operand_[2]) = arg2;
operand_[4] = arg3; operand_[5] = arg4; operand_[6] = arg5;
operand_[7] = arg6; operand_[8] = arg7; operand_[9] = arg8;
operand_[10] = arg9;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9) {
initList(9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10){
initList(10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
};
PCIOperandList(Int64 arg1, Int64 arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11){
numberOperands_ = 13;
*((Int64*)&operand_[0]) = arg1; *((Int64*)&operand_[2]) = arg2;
operand_[4] = arg3; operand_[5] = arg4; operand_[6] = arg5;
operand_[7] = arg6; operand_[8] = arg7; operand_[9] = arg8;
operand_[10] = arg9; operand_[11] = arg10; operand_[12] = arg11;
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11){
initList(11, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12){
initList(12, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13){
initList(13, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14){
initList(14, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14, PCIType::Operand arg15){
initList(15, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14,
PCIType::Operand arg15, PCIType::Operand arg16){
initList(16, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14,
PCIType::Operand arg15, PCIType::Operand arg16, PCIType::Operand arg17){
initList(17, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14,
PCIType::Operand arg15, PCIType::Operand arg16, PCIType::Operand arg17, PCIType::Operand arg18){
initList(18, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14,
PCIType::Operand arg15, PCIType::Operand arg16, PCIType::Operand arg17, PCIType::Operand arg18,
PCIType::Operand arg19){
initList(19, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);
};
PCIOperandList(PCIType::Operand arg1, PCIType::Operand arg2, PCIType::Operand arg3, PCIType::Operand arg4, PCIType::Operand arg5,
PCIType::Operand arg6, PCIType::Operand arg7, PCIType::Operand arg8, PCIType::Operand arg9, PCIType::Operand arg10,
PCIType::Operand arg11, PCIType::Operand arg12, PCIType::Operand arg13, PCIType::Operand arg14,
PCIType::Operand arg15, PCIType::Operand arg16, PCIType::Operand arg17, PCIType::Operand arg18,
PCIType::Operand arg19, PCIType::Operand arg20){
initList(20, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19,
arg20);
};
// Accessors
//
Int32 getNumberOperands() { return numberOperands_; };
PCIType::Operand getOperand(Int32 op) { return operand_[op]; };
private:
// Helper for constuctors
//
void initList(Int32 numberOperands,
PCIType::Operand op1 =0, PCIType::Operand op2 =0, PCIType::Operand op3 =0, PCIType::Operand op4 =0,
PCIType::Operand op5 =0, PCIType::Operand op6 =0, PCIType::Operand op7 =0, PCIType::Operand op8 =0,
PCIType::Operand op9 =0, PCIType::Operand op10 =0, PCIType::Operand op11 =0, PCIType::Operand op12 =0,
PCIType::Operand op13 =0, PCIType::Operand op14 =0, PCIType::Operand op15 =0, PCIType::Operand op16 =0,
PCIType::Operand op17 =0, PCIType::Operand op18 =0, PCIType::Operand op19 =0, PCIType::Operand op20 =0) {
numberOperands_ = numberOperands;
operand_[0] = op1; operand_[1] = op2; operand_[2] = op3;
operand_[3] = op4; operand_[4] = op5; operand_[5] = op6;
operand_[6] = op7; operand_[7] = op8; operand_[8] = op9;
operand_[9] = op10; operand_[10] = op11; operand_[11] = op12;
operand_[12] = op13; operand_[13] = op14; operand_[14] = op15;
operand_[15] = op16; operand_[16] = op17; operand_[17] = op18;
operand_[18] = op19; operand_[19] = op20;
};
// numberOperands_ - Indicates the number of operands that are valid (0-6).
// Is set automatically by the constructor and is read-only otherwise.
// Can be queried with the getNumberOperands() method.
//
Int32 numberOperands_;
// operand_ - A vector of operands. Is set automatically by the
// constructor and is read-only otherwise. Can be queried with the
// getOperand() accessor.
//
PCIType::Operand operand_[20];
};
// PCodeInstruction (PCI for short)
//
// The PCodeInstruction class is used to encapsulate a PCODE operation which
// consists of an operation, 0 to 3 addressing modes, and 0 to 6 operands.
// PCI's are NOT the actual byte codes that are interpreted at execution
// time, but one level higher. It may be helpful to think of PCI's as
// analogous to assembly code and the byte codes that are intpreted at
// execution time as analogous to machine code.
//
//
class PCodeInstruction {
public:
// Constructors
//
PCodeInstruction(PCIType::Operation operation) {
AML aml;
OL ol;
init(operation, aml, ol);
};
PCodeInstruction(PCIType::Operation operation, AML &aml) {
OL ol;
init(operation, aml, ol);
};
PCodeInstruction(PCIType::Operation operation, AML &aml, OL &ol) {
init(operation, aml, ol);
}
PCodeInstruction(const PCodeInstruction *pci) { copy(pci); };
// Accessors
//
Int32 getNumberAddressingModes() { return numberAddressingModes_; };
Int32 getNumberOperands() { return numberOperands_; };
void setNumberOperands(Int32 numOperands) { numberOperands_ = numOperands; };
void replaceAddressingModesAndOperands(AML &aml, OL &ol) {
numberAddressingModes_ = aml.getNumberAddressingModes();
Int32 i = 0;
for(; i<numberAddressingModes_; i++)
addressingMode_[i] = aml.getAddressingMode(i);
numberOperands_ = ol.getNumberOperands();
for(i=0; i<numberOperands_; i++)
operand_[i] = ol.getOperand(i);
};
PCIType::Operation getOperation() { return operation_; };
PCIType::AddressingMode getAddressingMode(Int32 am)
{ return addressingMode_[am]; };
Long getLongOperand(Int32 op) { return *(Long*)&operand_[op]; };
PCIType::Operand getOperand(Int32 op) { return operand_[op]; };
void setLongOperand(Int32 op, Long val) { *(Long*)&operand_[op] = val; };
void setOperand(Int32 op, PCIType::Operand val) { operand_[op] = val; };
Int32 getCodePosition() const { return codePosition_; };
void setCodePosition(Int32 codePosition) { codePosition_ = codePosition; };
Int32 getStackChange();
Int32 getGeneratedCodeSize();
// Helpers
//
static Int32 temporaryStoreLoadMatch(PCodeInstruction *store, PCodeInstruction *load);
static Int32 temporaryStoreLoadOverlap(PCodeInstruction *store, PCodeInstruction *load);
static Int32 replaceUsesOfTarget(PCodeInstruction *store, PCodeInstruction *use, Int32 check);
Int32 getMemoryOperandLength(PCIType::AddressingMode, Int32 operand);
// Display
//
void print();
private:
// Private helper for constructors
//
void init(PCIType::Operation operation, AML &aml, OL &ol) {
operation_ = operation;
numberAddressingModes_ = aml.getNumberAddressingModes();
Int32 i = 0;
for(; i<numberAddressingModes_; i++)
addressingMode_[i] = aml.getAddressingMode(i);
numberOperands_ = ol.getNumberOperands();
for(i=0; i<numberOperands_; i++)
operand_[i] = ol.getOperand(i);
};
// Private helper for constructors
//
void copy(const PCodeInstruction *pci) {
operation_ = pci->operation_;
numberAddressingModes_ = pci->numberAddressingModes_;
numberOperands_ = pci->numberOperands_;
Int32 i = 0;
for(; i<numberAddressingModes_; i++)
addressingMode_[i] = pci->addressingMode_[i];
for(i=0; i<numberOperands_; i++)
operand_[i] = pci->operand_[i];
};
// operation_ - Indicates the type of operation (i.e. load, store, etc).
// Is set by the constructor and is read-only otherwise. Can be queried
// using the getOperation() accessor.
//
PCIType::Operation operation_;
// addressingMode_ - Vector of addressing modes for this PCI. Is set
// by the constructor and is read-only otherwise. Can be queried using
// the getAddressingMode() accessor.
//
PCIType::AddressingMode addressingMode_[6];
// operand_ - Vector of operands for this PCI. Is set by the constructor.
// Can be queried using the getOperand() accessor and modified using the
// setOperand() method. However, only existing operands can be changed.
//
PCIType::Operand operand_[20];
// numberAddressingModes_ - Indicates the number of valid addressing modes.
// Is set automatically by the constructor and is read-only otherwise.
// Can be queried with the getNumberAddressingModes() accessor.
//
Int32 numberAddressingModes_;
// numberOperands_ - Indicates the number of valid operands.
// Is set automatically by the constructor and is read-only otherwise.
// Can be queried with the getNumberOperands() accessor.
//
Int32 numberOperands_;
// codePosition_ - Indicates integer offset of the beggining of this
// PCI in the generated byte code stream. Can be queried using the
// getCodePosition() accesor and set using the setCodePosition() method.
//
Int32 codePosition_;
};
// A general method to take pointers out of PCode binary stream
// Takes pointer out of PCodeBinary sequences
#define GetPCodeBinaryAsPtr(pcode, idx) (*(Long*)&(pcode[idx]))
#endif // ExpPCodeInstruction_h