gecko-dev/ef/Compiler/PrimitiveGraph/PrimitiveOperations

354 lines
20 KiB
Plaintext

// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
//
// The contents of this file are subject to the Netscape Public License
// Version 1.0 (the "NPL"); you may not use this file except in
// compliance with the NPL. You may obtain a copy of the NPL at
// http://www.mozilla.org/NPL/
//
// Software distributed under the NPL is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
// for the specific language governing rights and limitations under the
// NPL.
//
// The Initial Developer of this code under the NPL is Netscape
// Communications Corporation. Portions created by Netscape are
// Copyright (C) 1998 Netscape Communications Corporation. All Rights
// Reserved.
//
// Here's the syntax of the PrimitiveOperations table entries expressed as a BNF grammar.
// These entries are converted into several different tables inside DataNodeTemplates.cpp
// and PrimitiveOperations.h.
//
// table-entry ::= '{' primitiveOperation ',' primitiveCategory ',' usage '}'
//
// usage ::= '"' outputs ':' inputs '"' | null-usage
//
// null-usage ::= '""' // indicates that this is not a legal primitive
//
// outputs ::= exception | arg | exception arg | root
//
// inputs ::= arg* | arg* repeat-arg | root
//
// repeat-arg ::= arg '*' // zero or more arguments that satisfy the given arg pattern
//
// arg ::= arg-origin arg-kind | short-arg
//
// arg-origin ::= 'V' | // variable
// 'C' | // constant
// 'A' // either variable or constant
//
// arg-kind ::= 'v' | // void
// 'i' | // integer
// 'l' | // long
// 'f' | // float
// 'd' | // double
// 'a' | // address
// 'c' | // condition
// 'm' | // memory
// 't' | // tuple
// '@' // any of the above arg-kinds except memory or tuple
//
// short-arg ::= 'M' | // same as 'Vm'
// 'T' // same as 'Vt'
//
// exception ::= 'E' // flag that indicates that this primitive causes exceptions
// // (sets fnCanRaiseException and fnIsRoot)
//
// root ::= 'Z' // flag that indicates that this primitive is attached to a control node (sets fnIsRoot)
//
ARG-ORIGIN 'V' aoVariable;
ARG-ORIGIN 'C' aoConstant;
ARG-ORIGIN 'A' aoEither;
ARG-KIND 'v' vkVoid;
ARG-KIND 'i' vkInt;
ARG-KIND 'l' vkLong;
ARG-KIND 'f' vkFloat;
ARG-KIND 'd' vkDouble;
ARG-KIND 'a' vkAddr;
ARG-KIND 'c' vkCond;
ARG-KIND 'm' vkMemory;
ARG-KIND 't' vkTuple;
SHORT-ARG 'M' vkMemory;
SHORT-ARG 'T' vkTuple;
{poNone, pcNone, ""}
{poPhi_I, pcPhi, "Vi:Ai*"} // 32-bit integer phi node Aint ... Aint -> Vint
{poPhi_L, pcPhi, "Vl:Al*"} // 64-bit integer phi node Along ... Along -> Vlong
{poPhi_F, pcPhi, "Vf:Af*"} // 32-bit float phi node Afloat ... Afloat -> Vfloat
{poPhi_D, pcPhi, "Vd:Ad*"} // 64-bit float phi node Adouble ... Adouble -> Vdouble
{poPhi_A, pcPhi, "Va:Aa*"} // Pointer phi node Aaddr ... Aaddr -> Vaddr
{poPhi_C, pcPhi, "Vc:Ac*"} // Condition phi node Acond ... Acond -> Vcond
{poPhi_M, pcPhi, "M:M*"} // Memory phi node M ... M -> M
{poConst_I, pcConst, "Vi:Ci"} // 32-bit integer constant Cint -> Vint
{poConst_L, pcConst, "Vl:Cl"} // 64-bit integer constant Clong -> Vlong
{poConst_F, pcConst, "Vf:Cf"} // 32-bit float constant Cfloat -> Vfloat
{poConst_D, pcConst, "Vd:Cd"} // 64-bit float constant Cdouble -> Vdouble
{poConst_A, pcConst, "Va:Ca"} // Pointer constant Caddr -> Vaddr
{poConst_C, pcConst, "Vc:Cc"} // Condition constant Ccond -> Vcond
{poConst_M, pcConst, "M:Cm"} // Memory constant Cmemory -> M
{poProj_I, pcProj, "Vi:T"} // 32-bit integer extracted from tuple T -> Vint
{poProj_L, pcProj, "Vl:T"} // 64-bit integer extracted from tuple T -> Vlong
{poProj_F, pcProj, "Vf:T"} // 32-bit float extracted from tuple T -> Vfloat
{poProj_D, pcProj, "Vd:T"} // 64-bit float extracted from tuple T -> Vdouble
{poProj_A, pcProj, "Va:T"} // Pointer extracted from tuple T -> Vaddr
{poProj_C, pcNone, ""} // Condition extracted from tuple T -> Vcond (not used)
{poProj_M, pcProj, "M:T"} // Memory extracted from tuple T -> M
{poDebug, pcDebug, "M:MA@*"} // Breakpoint M, ... -> M
{poBreak, pcDebug, "M:MA@*"} // Breakpoint M, ... -> M
{poArg_I, pcArg, "Vi:Z"} // 32-bit integer argument -> Vint
{poArg_L, pcArg, "Vl:Z"} // 64-bit integer argument -> Vlong
{poArg_F, pcArg, "Vf:Z"} // 32-bit float argument -> Vfloat
{poArg_D, pcArg, "Vd:Z"} // 64-bit float argument -> Vdouble
{poArg_A, pcArg, "Va:Z"} // Pointer argument -> Vaddr
{poArg_C, pcNone, ""} // Condition argument -> Vcond (not used)
{poArg_M, pcArg, "M:Z"} // Argument representing all of memory -> M
{poResult_I, pcResult, "Z:Ai"} // 32-bit integer result Aint ->
{poResult_L, pcResult, "Z:Al"} // 64-bit integer result Along ->
{poResult_F, pcResult, "Z:Af"} // 32-bit float result Afloat ->
{poResult_D, pcResult, "Z:Ad"} // 64-bit float result Adouble ->
{poResult_A, pcResult, "Z:Aa"} // Pointer result Aaddr ->
{poResult_C, pcNone, ""} // Condition result Acond -> (not used)
{poResult_M, pcResult, "Z:M"} // Result representing all of memory M ->
// Cond lt eq gt un
{poIfLt, pcIfCond, "Z:Vc"} // If condition 1 0 0 0 Vcond ->
{poIfEq, pcIfCond, "Z:Vc"} // If condition 0 1 0 0 Vcond ->
{poIfLe, pcIfCond, "Z:Vc"} // If condition 1 1 0 0 Vcond ->
{poIfGt, pcIfCond, "Z:Vc"} // If condition 0 0 1 0 Vcond ->
{poIfLgt, pcIfCond, "Z:Vc"} // If condition 1 0 1 0 Vcond ->
{poIfGe, pcIfCond, "Z:Vc"} // If condition 0 1 1 0 Vcond ->
{poIfOrd, pcIfCond, "Z:Vc"} // If condition 1 1 1 0 Vcond ->
{poIfUnord, pcIfCond, "Z:Vc"} // If condition 0 0 0 1 Vcond ->
{poIfULt, pcIfCond, "Z:Vc"} // If condition 1 0 0 1 Vcond ->
{poIfUEq, pcIfCond, "Z:Vc"} // If condition 0 1 0 1 Vcond ->
{poIfULe, pcIfCond, "Z:Vc"} // If condition 1 1 0 1 Vcond ->
{poIfUGt, pcIfCond, "Z:Vc"} // If condition 0 0 1 1 Vcond ->
{poIfNe, pcIfCond, "Z:Vc"} // If condition 1 0 1 1 Vcond ->
{poIfUGe, pcIfCond, "Z:Vc"} // If condition 0 1 1 1 Vcond ->
{poSwitch, pcSwitch, "Z:Vi"} // Switch index node Vint ->
{poCatch, pcCatch, "Va:Z"} // Catch exception producer -> Vaddr
{poAnd_I, pcGeneric, "Vi:ViAi"} // Logical AND Vint & Aint -> Vint
{poAnd_L, pcGeneric, "Vl:VlAl"} // Logical AND Vlong & Along -> Vlong
{poOr_I, pcGeneric, "Vi:ViAi"} // Logical OR Vint | Aint -> Vint
{poOr_L, pcGeneric, "Vl:VlAl"} // Logical OR Vlong | Along -> Vlong
{poXor_I, pcGeneric, "Vi:ViAi"} // Logical XOR Vint ^ Aint -> Vint
{poXor_L, pcGeneric, "Vl:VlAl"} // Logical XOR Vlong ^ Along -> Vlong
{poAdd_I, pcGeneric, "Vi:ViAi"} // Add Vint + Aint -> Vint
{poAdd_L, pcGeneric, "Vl:VlAl"} // Add Vlong + Along -> Vlong
{poAdd_A, pcGeneric, "Va:AaAi"} // Add Aaddr + exts(Aint) -> Vaddr
{poAddU_A, pcGeneric, "Va:AaAi"} // Add Aaddr + extu(Aint) -> Vaddr
{poSub_I, pcGeneric, "Vi:AiVi"} // Subtract Aint - Vint -> Vint
{poSub_L, pcGeneric, "Vl:AlVl"} // Subtract Along - Vlong -> Vlong
{poSub_A, pcGeneric, "Va:AaVi"} // Subtract Aaddr - exts(Vint) -> Vaddr
{poSubU_A, pcGeneric, "Va:AaVi"} // Subtract Aaddr - extu(Vint) -> Vaddr
{poSubA_I, pcGeneric, "Vi:AaAa"} // Subtract addresses Aaddr - Aaddr -> Vint
{poMul_I, pcGeneric, "Vi:ViAi"} // Multiply Vint * Aint -> Vint
{poMul_L, pcGeneric, "Vl:VlAl"} // Multiply Vlong * Along -> Vlong
{poDiv_I, pcDivMod, "Vi:AiAi"} // Divide signed Aint /s Aint -> Vint
{poDiv_L, pcDivMod, "Vl:AlAl"} // Divide signed Along /s Along -> Vlong
{poDivE_I, pcDivMod, "EVi:AiVi"} // Divide signed exc Aint /s Vint -> Vint, E
{poDivE_L, pcDivMod, "EVl:AlVl"} // Divide signed exc Along /s Vlong -> Vlong, E
{poDivU_I, pcDivMod, "Vi:AiAi"} // Divide unsigned Aint /u Aint -> Vint
{poDivU_L, pcDivMod, "Vl:AlAl"} // Divide unsigned Along /u Along -> Vlong
{poDivUE_I, pcDivMod, "EVi:AiVi"} // Divide unsigned exc Aint /u Vint -> Vint, E
{poDivUE_L, pcDivMod, "EVl:AlVl"} // Divide unsigned exc Along /u Vlong -> Vlong, E
{poMod_I, pcDivMod, "Vi:AiAi"} // Modulo signed Aint %s Aint -> Vint
{poMod_L, pcDivMod, "Vl:AlAl"} // Modulo signed Along %s Along -> Vlong
{poModE_I, pcDivMod, "EVi:AiVi"} // Modulo signed exc Aint %s Vint -> Vint, E
{poModE_L, pcDivMod, "EVl:AlVl"} // Modulo signed exc Along %s Vlong -> Vlong, E
{poModU_I, pcDivMod, "Vi:AiAi"} // Modulo unsigned Aint %u Aint -> Vint
{poModU_L, pcDivMod, "Vl:AlAl"} // Modulo unsigned Along %u Along -> Vlong
{poModUE_I, pcDivMod, "EVi:AiVi"} // Modulo unsigned exc Aint %u Vint -> Vint, E
{poModUE_L, pcDivMod, "EVl:AlVl"} // Modulo unsigned exc Along %u Vlong -> Vlong, E
{poShl_I, pcShift, "Vi:AiAi"} // Shift left Aint << Aint -> Vint
{poShl_L, pcShift, "Vl:AlAi"} // Shift left Along << Aint -> Vlong
{poShr_I, pcShift, "Vi:AiAi"} // Shift right signed Aint >>s Aint -> Vint
{poShr_L, pcShift, "Vl:AlAi"} // Shift right signed Along >>s Aint -> Vlong
{poShrU_I, pcShift, "Vi:AiAi"} // Shift right unsigned Aint >>u Aint -> Vint
{poShrU_L, pcShift, "Vl:AlAi"} // Shift right unsigned Along >>u Aint -> Vlong
{poExt_I, pcExt, "Vi:ViCi"} // Signed field extract Vint, Cint -> Vint
{poExt_L, pcExt, "Vl:VlCi"} // Signed field extract Vlong, Cint -> Vlong
{poFAdd_F, pcFGeneric, "Vf:VfAf"} // FP add Vfloat + Afloat -> Vfloat
{poFAdd_D, pcFGeneric, "Vd:VdAd"} // FP add Vdouble + Adouble -> Vdouble
{poFSub_F, pcFGeneric, "Vf:AfVf"} // FP subtract Afloat - Vfloat -> Vfloat
{poFSub_D, pcFGeneric, "Vd:AdVd"} // FP subtract Adouble - Vdouble -> Vdouble
{poFMul_F, pcFGeneric, "Vf:VfAf"} // FP multiply Vfloat * Afloat -> Vfloat
{poFMul_D, pcFGeneric, "Vd:VdAd"} // FP multiply Vdouble * Adouble -> Vdouble
{poFDiv_F, pcFGeneric, "Vf:AfAf"} // FP divide Afloat / Afloat -> Vfloat
{poFDiv_D, pcFGeneric, "Vd:AdAd"} // FP divide Adouble / Adouble -> Vdouble
{poFRem_F, pcFGeneric, "Vf:AfAf"} // FP Java remainder Afloat rem Afloat -> Vfloat
{poFRem_D, pcFGeneric, "Vd:AdAd"} // FP Java remainder Adouble rem Adouble -> Vdouble
{poConvI_L, pcConv, "Vi:Vl"} // Convert Vlong -> Vint
{poConvL_I, pcConv, "Vl:Vi"} // Convert exts(Vint) -> Vlong
{poFConvI_F, pcFConv, "Vi:Vf"} // FP convert Vfloat -> Vint
{poFConvI_D, pcFConv, "Vi:Vd"} // FP convert Vdouble -> Vint
{poFConvL_F, pcFConv, "Vl:Vf"} // FP convert Vfloat -> Vlong
{poFConvL_D, pcFConv, "Vl:Vd"} // FP convert Vdouble -> Vlong
{poFConvF_I, pcFConv, "Vf:Vi"} // FP convert Vint -> Vfloat
{poFConvF_L, pcFConv, "Vf:Vl"} // FP convert Vlong -> Vfloat
{poFConvF_D, pcFConv, "Vf:Vd"} // FP convert Vdouble -> Vfloat
{poFConvD_I, pcFConv, "Vd:Vi"} // FP convert Vint -> Vdouble
{poFConvD_L, pcFConv, "Vd:Vl"} // FP convert Vlong -> Vdouble
{poFConvD_F, pcFConv, "Vd:Vf"} // FP convert Vfloat -> Vdouble
{poCmp_I, pcCmp, "Vc:ViAi"} // Compare signed Vint ?s Aint -> Vcond
{poCmp_L, pcCmp, "Vc:VlAl"} // Compare signed Vlong ?s Along -> Vcond
{poCmpU_I, pcCmp, "Vc:ViAi"} // Compare unsigned Vint ?u Aint -> Vcond
{poCmpU_L, pcCmp, "Vc:VlAl"} // Compare unsigned Vlong ?u Along -> Vcond
{poCmpU_A, pcCmp, "Vc:VaAa"} // Compare unsigned Vaddr ?u Aaddr -> Vcond
{poFCmp_F, pcFCmp, "Vc:VfAf"} // FP compare Vfloat ? Afloat -> Vcond
{poFCmp_D, pcFCmp, "Vc:VdAd"} // FP compare Vdouble ? Adouble -> Vcond
// Cond lt eq gt un
{poLt_I, pcCond, "Vi:Vc"} // conditional 1 0 0 0 Vcond -> Vint
{poEq_I, pcCond, "Vi:Vc"} // conditional 0 1 0 0 Vcond -> Vint
{poLe_I, pcCond, "Vi:Vc"} // conditional 1 1 0 0 Vcond -> Vint
{poGt_I, pcCond, "Vi:Vc"} // conditional 0 0 1 0 Vcond -> Vint
{poLgt_I, pcCond, "Vi:Vc"} // conditional 1 0 1 0 Vcond -> Vint
{poGe_I, pcCond, "Vi:Vc"} // conditional 0 1 1 0 Vcond -> Vint
{poOrd_I, pcCond, "Vi:Vc"} // conditional 1 1 1 0 Vcond -> Vint
{poUnord_I, pcCond, "Vi:Vc"} // conditional 0 0 0 1 Vcond -> Vint
{poULt_I, pcCond, "Vi:Vc"} // conditional 1 0 0 1 Vcond -> Vint
{poUEq_I, pcCond, "Vi:Vc"} // conditional 0 1 0 1 Vcond -> Vint
{poULe_I, pcCond, "Vi:Vc"} // conditional 1 1 0 1 Vcond -> Vint
{poUGt_I, pcCond, "Vi:Vc"} // conditional 0 0 1 1 Vcond -> Vint
{poNe_I, pcCond, "Vi:Vc"} // conditional 1 0 1 1 Vcond -> Vint
{poUGe_I, pcCond, "Vi:Vc"} // conditional 0 1 1 1 Vcond -> Vint
// Cond3 lt eq gt un
{poCatL_I, pcCond3, "Vi:Vc"} // conditional -1 0 1 -1 Vcond -> Vint
{poCatG_I, pcCond3, "Vi:Vc"} // conditional -1 0 1 1 Vcond -> Vint
{poCatCL_I, pcCond3, "Vi:Vc"} // conditional 1 0 -1 -1 Vcond -> Vint
{poCatCG_I, pcCond3, "Vi:Vc"} // conditional 1 0 -1 1 Vcond -> Vint
{poChkNull, pcCheck1, "E:Va"} // Throw NullPointerException if null Vaddr -> E
{poChkCast_I, pcCheck2, "E:ViAi"} // Throw ClassCastException if != Vint, Aint -> E
{poChkCast_A, pcCheck2, "E:VaAa"} // Throw ClassCastException if != Vaddr, Aaddr -> E
{poLimit, pcCheck2, "E:AiAi"} // Throw ArrayIndexOutOfBounds if >=u Aint, Aint -> E
{poLimCast, pcCheck2, "E:ViCi"} // Throw ClassCastException if < Vint, Cint -> E
{poLd_I, pcLd, "Vi:AmAa"} // Load M, *Aaddr -> Vint
{poLd_L, pcLd, "Vl:AmAa"} // Load M, *Aaddr -> Vlong
{poLd_F, pcLd, "Vf:AmAa"} // Load M, *Aaddr -> Vfloat
{poLd_D, pcLd, "Vd:AmAa"} // Load M, *Aaddr -> Vdouble
{poLd_A, pcLd, "Va:AmAa"} // Load M, *Aaddr -> Vaddr
{poLdE_I, pcLd, "EVi:AmVa"} // Load checked M, *Vaddr -> Vint, E
{poLdE_L, pcLd, "EVl:AmVa"} // Load checked M, *Vaddr -> Vlong, E
{poLdE_F, pcLd, "EVf:AmVa"} // Load checked M, *Vaddr -> Vfloat, E
{poLdE_D, pcLd, "EVd:AmVa"} // Load checked M, *Vaddr -> Vdouble, E
{poLdE_A, pcLd, "EVa:AmVa"} // Load checked M, *Vaddr -> Vaddr, E
{poLdS_B, pcLd, "Vi:AmAa"} // Load signed byte M, exts(*Aaddr) -> Vint
{poLdS_H, pcLd, "Vi:AmAa"} // Load signed halfword M, exts(*Aaddr) -> Vint
{poLdSE_B, pcLd, "EVi:AmVa"} // Load signed checked byte M, exts(*Vaddr) -> Vint, E
{poLdSE_H, pcLd, "EVi:AmVa"} // Load signed checked halfword M, exts(*Vaddr) -> Vint, E
{poLdU_B, pcLd, "Vi:AmAa"} // Load unsigned byte M, extu(*Aaddr) -> Vint
{poLdU_H, pcLd, "Vi:AmAa"} // Load unsigned halfword M, extu(*Aaddr) -> Vint
{poLdUE_B, pcLd, "EVi:AmVa"} // Load unsigned checked byte M, extu(*Vaddr) -> Vint, E
{poLdUE_H, pcLd, "EVi:AmVa"} // Load unsigned checked halfword M, extu(*Vaddr) -> Vint, E
{poLdV_I, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vint
{poLdV_L, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vlong
{poLdV_F, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vfloat
{poLdV_D, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vdouble
{poLdV_A, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vaddr
{poLdVE_I, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vint, E
{poLdVE_L, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vlong, E
{poLdVE_F, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vfloat, E
{poLdVE_D, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vdouble, E
{poLdVE_A, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vaddr, E
{poLdVS_B, pcLd, "T:MAa"} // Load volatile signed byte M, exts(*Aaddr) -> M, Vint
{poLdVS_H, pcLd, "T:MAa"} // Load volatile signed halfword M, exts(*Aaddr) -> M, Vint
{poLdVSE_B, pcLd, "ET:MVa"} // Load volatile signed checked byte M, exts(*Vaddr) -> M, Vint, E
{poLdVSE_H, pcLd, "ET:MVa"} // Load volatile signed checked hfwrd M, exts(*Vaddr) -> M, Vint, E
{poLdVU_B, pcLd, "T:MAa"} // Load volatile unsigned byte M, extu(*Aaddr) -> M, Vint
{poLdVU_H, pcLd, "T:MAa"} // Load volatile unsigned halfword M, extu(*Aaddr) -> M, Vint
{poLdVUE_B, pcLd, "ET:MVa"} // Load volatile unsigned checked byte M, extu(*Vaddr) -> M, Vint, E
{poLdVUE_H, pcLd, "ET:MVa"} // Load volatile unsigned checked hfwrd M, extu(*Vaddr) -> M, Vint, E
{poSt_B, pcSt, "M:MAaAi"} // Store byte M, Aaddr, Aint -> M
{poSt_H, pcSt, "M:MAaAi"} // Store halfword M, Aaddr, Aint -> M
{poSt_I, pcSt, "M:MAaAi"} // Store M, Aaddr, Aint -> M
{poSt_L, pcSt, "M:MAaAl"} // Store M, Aaddr, Along -> M
{poSt_F, pcSt, "M:MAaAf"} // Store M, Aaddr, Afloat -> M
{poSt_D, pcSt, "M:MAaAd"} // Store M, Aaddr, Adouble -> M
{poSt_A, pcSt, "M:MAaAa"} // Store M, Aaddr, Aaddr -> M
{poStE_B, pcSt, "EM:MVaAi"} // Store byte checked M, Vaddr, Aint -> M, E
{poStE_H, pcSt, "EM:MVaAi"} // Store halfword checked M, Vaddr, Aint -> M, E
{poStE_I, pcSt, "EM:MVaAi"} // Store checked M, Vaddr, Aint -> M, E
{poStE_L, pcSt, "EM:MVaAl"} // Store checked M, Vaddr, Along -> M, E
{poStE_F, pcSt, "EM:MVaAf"} // Store checked M, Vaddr, Afloat -> M, E
{poStE_D, pcSt, "EM:MVaAd"} // Store checked M, Vaddr, Adouble -> M, E
{poStE_A, pcSt, "EM:MVaAa"} // Store checked M, Vaddr, Aaddr -> M, E
{poStV_B, pcSt, "M:MAaAi"} // Store volatile byte M, Aaddr, Aint -> M
{poStV_H, pcSt, "M:MAaAi"} // Store volatile halfword M, Aaddr, Aint -> M
{poStV_I, pcSt, "M:MAaAi"} // Store volatile M, Aaddr, Aint -> M
{poStV_L, pcSt, "M:MAaAl"} // Store volatile M, Aaddr, Along -> M
{poStV_F, pcSt, "M:MAaAf"} // Store volatile M, Aaddr, Afloat -> M
{poStV_D, pcSt, "M:MAaAd"} // Store volatile M, Aaddr, Adouble -> M
{poStV_A, pcSt, "M:MAaAa"} // Store volatile M, Aaddr, Aaddr -> M
{poStVE_B, pcSt, "EM:MVaAi"} // Store volatile byte checked M, Vaddr, Aint -> M, E
{poStVE_H, pcSt, "EM:MVaAi"} // Store volatile halfword checked M, Vaddr, Aint -> M, E
{poStVE_I, pcSt, "EM:MVaAi"} // Store volatile checked M, Vaddr, Aint -> M, E
{poStVE_L, pcSt, "EM:MVaAl"} // Store volatile checked M, Vaddr, Along -> M, E
{poStVE_F, pcSt, "EM:MVaAf"} // Store volatile checked M, Vaddr, Afloat -> M, E
{poStVE_D, pcSt, "EM:MVaAd"} // Store volatile checked M, Vaddr, Adouble -> M, E
{poStVE_A, pcSt, "EM:MVaAa"} // Store volatile checked M, Vaddr, Aaddr -> M, E
{poMEnter, pcMonitor, "EM:MAa"} // Acquire a monitor M, Aaddr -> M, E
{poMExit, pcMonitor, "M:MAa"} // Release a monitor M, Aaddr -> M
{poSync, pcSync, "M:M"} // Memory barrier M -> M
{poSysCall, pcSysCall, "T:MA@*"} // System call M, ... -> V@
{poSysCallV, pcSysCall, "T:MA@*"} // Volatile system call M, ... -> M, V@
{poSysCallC, pcSysCall, "T:A@*"} // Constant system call ... -> V@
{poSysCallE, pcSysCall, "ET:MA@*"} // System call exc M, ... -> V@, E
{poSysCallEV, pcSysCall, "ET:MA@*"} // Volatile system call exc M, ... -> M, V@, E
{poSysCallEC, pcSysCall, "ET:A@*"} // Constant system call exc ... -> V@, E
{poCall, pcCall, "ET:MAaA@*"} // Function call M, Va, ... -> M, V@, E
// code generator specific primitives
{coReg_V, pcNone, ""} // fake register (doesn't exist)
{coReg_I, pcNone, "Vi:"} // fake register ... -> Vint
{coReg_L, pcNone, "Vl:"} // fake register ... -> Vlong
{coReg_F, pcNone, "Vf:"} // fake register ... -> Vfloat
{coReg_D, pcNone, "Vd:"} // fake register ... -> Vdouble
{coReg_A, pcNone, "Va:"} // fake register ... -> Vaddr
{coReg_C, pcNone, "Vc:"} // fake register ... -> Vcond
{coReg_M, pcNone, "M:"} // fake register ... -> M
{coReg_T, pcNone, ""} // fake register (doesn't exist)