import json
import os

MAGIC = 0x07230203
GENERATOR_MAGIC = 0
VERSION = 99

with open(os.path.join(os.path.dirname(__file__), 'spirv.json')) as fd:
    TABLES = json.load(fd)

OPCODE_TABLE = {}
OPNAME_TABLE = {}
for fmt in TABLES['instructions']:
    OPCODE_TABLE[fmt['opcode']] = fmt
    OPNAME_TABLE[fmt['name']] = fmt

CONSTANTS = TABLES['constants']
DECORATIONS = CONSTANTS['Decoration']
MASKS = TABLES['masks']

BASIC_BLOCK_ENDING_INSTRUCTIONS = [
    'OpReturnValue',
    'OpBranch',
    'OpBranchConditional',
    'OpReturn',
    'OpKill',
    'OpUnreachable',
    'OpSwitch'
]

INITIAL_INSTRUCTIONS = [
    'OpSource',
    'OpSourceExtension',
    'OpCompileFlag',
    'OpExtension',
    'OpExtInstImport',
    'OpMemoryModel',
    'OpEntryPoint',
    'OpExecutionMode'
]

DEBUG_INSTRUCTIONS = [
    'OpString',
    'OpName',
    'OpMemberName',
    'OpLine',
]

DECORATION_INSTRUCTIONS = [
    'OpDecorate',
    'OpMemberDecorate',
    'OpGroupDecorate',
    'OpGroupMemberDecorate',
    'OpDecorationGroup'
]

TYPE_DECLARATION_INSTRUCTIONS = [
    'OpTypeVoid',
    'OpTypeBool',
    'OpTypeInt',
    'OpTypeFloat',
    'OpTypeVector',
    'OpTypeMatrix',
    'OpTypeSampler',
    'OpTypeFilter',
    'OpTypeArray',
    'OpTypeRuntimeArray',
    'OpTypeStruct',
    'OpTypeOpaque',
    'OpTypePointer',
    'OpTypeFunction',
    'OpTypeEvent',
    'OpTypeDeviceEvent',
    'OpTypeReserveId',
    'OpTypeQueue',
    'OpTypePipe'
]

CONSTANT_INSTRUCTIONS = [
    'OpConstantTrue',
    'OpConstantFalse',
    'OpConstant',
    'OpConstantComposite',
    'OpConstantSampler',
    'OpConstantNullPointer',
    'OpConstantNullObject',

    'OpSpecConstantTrue',
    'OpSpecConstantFalse',
    'OpSpecConstant',
    'OpSpecConstantComposite'
]

GLOBAL_VARIABLE_INSTRUCTIONS = [
    'OpVariable',
    'OpVariableArray'
]

GLOBAL_INSTRUCTIONS = (INITIAL_INSTRUCTIONS +
                       DEBUG_INSTRUCTIONS +
                       DECORATION_INSTRUCTIONS +
                       TYPE_DECLARATION_INSTRUCTIONS +
                       CONSTANT_INSTRUCTIONS +
                       GLOBAL_VARIABLE_INSTRUCTIONS)

HAS_SIDE_EFFECT = [
    'OpFunction',
    'OpFunctionParameter',
    'OpFunctionCall',
    'OpExtInst',
    'OpAtomicExchange',
    'OpAtomicCompareExchange',
    'OpAtomicCompareExchangeWeak',
    'OpAtomicIIncrement',
    'OpAtomicIDecrement',
    'OpAtomicIAdd',
    'OpAtomicISub',
    'OpAtomicUMin',
    'OpAtomicUMax',
    'OpAtomicAnd',
    'OpAtomicOr',
    'OpAtomicXor',
    'OpLabel',
    'OpAsyncGroupCopy',
    'OpWaitGroupEvents',
    'OpGroupAll',
    'OpGroupAny',
    'OpGroupBroadcast',
    'OpGroupIAdd',
    'OpGroupFAdd',
    'OpGroupFMin',
    'OpGroupUMin',
    'OpGroupSMin',
    'OpGroupFMax',
    'OpGroupUMax',
    'OpGroupSMax',
    'OpReadPipe',
    'OpWritePipe',
    'OpReservedReadPipe',
    'OpReservedWritePipe',
    'OpReserveReadPipePackets',
    'OpReserveWritePipePackets',
    'OpGroupReserveWritePipePackets',
    'OpEnqueueMarker',
    'OpEnqueueKernel',
    'OpCreateUserEvent',
    'OpAtomicIMin',
    'OpAtomicIMax'
]

@@ -649,29 +649,8 @@
 n',%0A
-    'OpCompileFlag',%0A
     
@@ -1134,24 +1134,43 @@
 ypeMatrix',%0A
+    'OpTypeImage',%0A
     'OpTypeS
@@ -1174,24 +1174,50 @@
 peSampler',%0A
+    'OpTypeSampledImage',%0A
     'OpTypeF
@@ -1480,24 +1480,46 @@
 UCTIONS = %5B%0A
+    'OpConstantNull',%0A
     'OpConst
@@ -1624,65 +1624,8 @@
 er',
-%0A    'OpConstantNullPointer',%0A    'OpConstantNullObject',
 %0A%0A  
@@ -1726,16 +1726,40 @@
 mposite'
+,%0A    'OpSpecConstantOp'
 %0A%5D%0A%0AGLOB
@@ -1807,31 +1807,8 @@
 ble'
-,%0A    'OpVariableArray'
 %0A%5D%0A%0A
@@ -2401,20 +2401,60 @@
 OpAtomic
-UMin
+SMin',%0A    'OpAtomicUMin',%0A    'OpAtomicSMax
 ',%0A    '
@@ -3066,47 +3066,7 @@
 ent'
-,%0A    'OpAtomicIMin',%0A    'OpAtomicIMax'
 %0A%5D%0A

Update for rev. 31 of the SPIR-V spec.