// -*- 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.1 (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.mozilla.org/NPL/
//
// Software distributed under the License is distributed on an "AS
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
// implied. See the License for the specific language governing
// rights and limitations under the License.
//
// The Original Code is mozilla.org code.
//
// The Initial Developer of the Original Code is Netscape
// Communications Corporation.  Portions created by Netscape are
// Copyright (C) 1998 Netscape Communications Corporation. All
// Rights Reserved.
//
// Contributor(s): 
//
// 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)
