Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
4,332
Issues
4,332
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
370
Merge Requests
370
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Glasgow Haskell Compiler
GHC
Commits
55f6344c
Commit
55f6344c
authored
Dec 06, 2000
by
sewardj
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[project @ 2000-12-06 15:23:31 by sewardj]
Tons of tedious crud which we will henceforth refer to politely as "the bytecode assembler".
parent
65464267
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
399 additions
and
549 deletions
+399
-549
ghc/compiler/ghci/ByteCodeGen.lhs
ghc/compiler/ghci/ByteCodeGen.lhs
+364
-77
ghc/rts/Bytecodes.h
ghc/rts/Bytecodes.h
+35
-472
No files found.
ghc/compiler/ghci/ByteCodeGen.lhs
View file @
55f6344c
...
...
@@ -4,21 +4,17 @@
\section[ByteCodeGen]{Generate bytecode from Core}
\begin{code}
module ByteCodeGen ( byteCodeGen ) where
module ByteCodeGen ( byteCodeGen
, assembleBCO
) where
#include "HsVersions.h"
--import Id
--import Name
--import PrimOp
import Outputable
import Name ( Name, getName )
import Id ( Id, idType, isDataConId_maybe )
import OrdList ( OrdList, consOL, snocOL, appOL, unitOL,
nilOL, toOL, concatOL, fromOL )
import FiniteMap ( FiniteMap, addListToFM, listToFM,
addToFM, lookupFM, fmToList )
addToFM, lookupFM, fmToList
, emptyFM
)
import CoreSyn
import Literal ( Literal(..) )
import PrimRep ( PrimRep(..) )
...
...
@@ -28,7 +24,15 @@ import DataCon ( DataCon, dataConTag, fIRST_TAG )
import Util ( zipEqual, zipWith4Equal, naturalMergeSortLe )
import VarSet ( VarSet, varSetElems )
import PrimRep ( getPrimRepSize, isFollowableRep )
--import FastTypes
import Constants ( wORD_SIZE )
import Foreign ( Addr, Word16, Word32, nullAddr )
import ST ( runST )
import MutableArray ( readWord32Array,
newFloatArray, writeFloatArray,
newDoubleArray, writeDoubleArray,
newIntArray, writeIntArray,
newAddrArray, writeAddrArray )
\end{code}
Entry point.
...
...
@@ -46,9 +50,15 @@ byteCodeGen binds
BcM_State bcos final_ctr -> bcos
\end{code}
The real machinery.
%************************************************************************
%* *
\subsection{Bytecodes, and Outputery.}
%* *
%************************************************************************
\begin{code}
type LocalLabel = Int
data BCInstr
...
...
@@ -81,26 +91,6 @@ data BCInstr
| CASEFAIL
-- To Infinity And Beyond
| ENTER
\end{code}
The object format for this is: 16 bits for the opcode, and 16 for each
field -- so the code can be considered a sequence of 16-bit ints.
Each field denotes either a stack offset or number of items on the
stack (eg SLIDE), and index into the pointer table (eg PUSH_G), an
index into the literal table (eg PUSH_I/D/L), or a bytecode address in
this BCO.
\begin{code}
--data BCO a = BCO [Word16] -- instructions
-- [Word8] -- literal pool
-- [a] -- Names or HValues
--assembleBCO :: ProtoBCO -> BCO
--assembleBCO (ProtoBCO nm instrs)
-- = -- pass 1: collect up the offsets of the local labels,
-- -- and also the literals and
instance Outputable BCInstr where
ppr (ARGCHECK n) = text "ARGCHECK" <+> int n
...
...
@@ -118,18 +108,24 @@ pprAltCode discrs_n_codes
= vcat (map f discrs_n_codes)
where f (discr, code) = ppr discr <> colon <+> vcat (map ppr (fromOL code))
type BCInstrList = OrdList BCInstr
data ProtoBCO a = ProtoBCO a BCInstrList
instance Outputable a => Outputable (ProtoBCO a) where
ppr (ProtoBCO name instrs)
= (text "ProtoBCO" <+> ppr name <> colon)
$$ nest 6 (vcat (map ppr (fromOL instrs)))
\end{code}
%************************************************************************
%* *
\subsection{Compilation schema for the bytecode generator.}
%* *
%************************************************************************
\begin{code}
type BCInstrList = OrdList BCInstr
data ProtoBCO a = ProtoBCO a BCInstrList
type Sequel = Int -- back off to this depth before ENTER
...
...
@@ -137,49 +133,6 @@ type Sequel = Int -- back off to this depth before ENTER
-- to mess with it after each push/pop.
type BCEnv = FiniteMap Id Int -- To find vars on the stack
lookupBCEnv :: BCEnv -> Id -> Int
lookupBCEnv env nm
= case lookupFM env nm of
Nothing -> pprPanic "lookupBCEnv"
(ppr nm $$ char ' ' $$ vcat (map ppr (fmToList env)))
Just xx -> xx
lookupBCEnv_maybe :: BCEnv -> Id -> Maybe Int
lookupBCEnv_maybe = lookupFM
-- Describes case alts
data Discr
= DiscrI Int
| DiscrF Float
| DiscrD Double
| DiscrP Int
| NoDiscr
instance Outputable Discr where
ppr (DiscrI i) = int i
ppr (DiscrF f) = text (show f)
ppr (DiscrD d) = text (show d)
ppr (DiscrP i) = int i
ppr NoDiscr = text "DEF"
-- When I push one of these on the stack, how much does Sp move by?
taggedSizeW :: PrimRep -> Int
taggedSizeW pr
| isFollowableRep pr = 1
| otherwise = 1{-the tag-} + getPrimRepSize pr
-- The plain size of something, without tag.
untaggedSizeW :: PrimRep -> Int
untaggedSizeW pr
| isFollowableRep pr = 1
| otherwise = getPrimRepSize pr
taggedIdSizeW, untaggedIdSizeW :: Id -> Int
taggedIdSizeW = taggedSizeW . typePrimRep . idType
untaggedIdSizeW = untaggedSizeW . typePrimRep . idType
-- Compile code for the right hand side of a let binding.
...
...
@@ -375,6 +328,7 @@ pushAtom False d p (AnnLit lit)
MachFloat r -> (PUSHU_F (fromRational r), untaggedSizeW FloatRep)
MachDouble r -> (PUSHU_D (fromRational r), untaggedSizeW DoubleRep)
-- Given a bunch of alts code and their discrs, do the donkey work
-- of making a multiway branch using a switch tree.
-- What a load of hassle!
...
...
@@ -471,9 +425,70 @@ mkMultiBranch raw_ways
maxD = 1.0e308
in
mkTree notd_ways init_lo init_hi
\end{code}
The bytecode generator's monad.
%************************************************************************
%* *
\subsection{Supporting junk for the compilation schemes}
%* *
%************************************************************************
\begin{code}
-- Describes case alts
data Discr
= DiscrI Int
| DiscrF Float
| DiscrD Double
| DiscrP Int
| NoDiscr
instance Outputable Discr where
ppr (DiscrI i) = int i
ppr (DiscrF f) = text (show f)
ppr (DiscrD d) = text (show d)
ppr (DiscrP i) = int i
ppr NoDiscr = text "DEF"
-- Find things in the BCEnv (the what's-on-the-stack-env)
lookupBCEnv :: BCEnv -> Id -> Int
lookupBCEnv env nm
= case lookupFM env nm of
Nothing -> pprPanic "lookupBCEnv"
(ppr nm $$ char ' ' $$ vcat (map ppr (fmToList env)))
Just xx -> xx
lookupBCEnv_maybe :: BCEnv -> Id -> Maybe Int
lookupBCEnv_maybe = lookupFM
-- When I push one of these on the stack, how much does Sp move by?
taggedSizeW :: PrimRep -> Int
taggedSizeW pr
| isFollowableRep pr = 1
| otherwise = 1{-the tag-} + getPrimRepSize pr
-- The plain size of something, without tag.
untaggedSizeW :: PrimRep -> Int
untaggedSizeW pr
| isFollowableRep pr = 1
| otherwise = getPrimRepSize pr
taggedIdSizeW, untaggedIdSizeW :: Id -> Int
taggedIdSizeW = taggedSizeW . typePrimRep . idType
untaggedIdSizeW = untaggedSizeW . typePrimRep . idType
\end{code}
%************************************************************************
%* *
\subsection{The bytecode generator's monad}
%* *
%************************************************************************
\begin{code}
data BcM_State
...
...
@@ -513,4 +528,276 @@ emitBc bco st
getLabelBc :: BcM Int
getLabelBc st
= (nextlabel st, st{nextlabel = 1 + nextlabel st})
\end{code}
%************************************************************************
%* *
\subsection{The bytecode assembler}
%* *
%************************************************************************
The object format for bytecodes is: 16 bits for the opcode, and 16 for
each field -- so the code can be considered a sequence of 16-bit ints.
Each field denotes either a stack offset or number of items on the
stack (eg SLIDE), and index into the pointer table (eg PUSH_G), an
index into the literal table (eg PUSH_I/D/L), or a bytecode address in
this BCO.
\begin{code}
-- An (almost) assembled BCO.
data BCO a = BCO [Word16] -- instructions
[Word32] -- literal pool
[a] -- Names or HValues
-- Top level assembler fn.
assembleBCO :: ProtoBCO Name -> BCO Name
assembleBCO (ProtoBCO nm instrs_ordlist)
= let
-- pass 1: collect up the offsets of the local labels
instrs = fromOL instrs_ordlist
label_env = mkLabelEnv emptyFM 0 instrs
mkLabelEnv env i_offset [] = env
mkLabelEnv env i_offset (i:is)
= let new_env
= case i of LABEL n -> addToFM env n i_offset ; _ -> env
in mkLabelEnv new_env (i_offset + instrSizeB i) is
findLabel lab
= case lookupFM label_env lab of
Just bco_offset -> bco_offset
Nothing -> pprPanic "assembleBCO.findLabel" (int lab)
-- pass 2: generate the instruction, ptr and nonptr bits
(insnW16s, litW32s, ptrs) = mkBits findLabel [] 0 [] 0 [] 0 instrs
in
BCO insnW16s litW32s ptrs
-- This is where all the action is (pass 2 of the assembler)
mkBits :: (Int -> Int) -- label finder
-> [Word16] -> Int -- reverse acc instr bits
-> [Word32] -> Int -- reverse acc literal bits
-> [Name] -> Int -- reverse acc ptrs
-> [BCInstr] -- insns!
-> ([Word16], [Word32], [Name])
mkBits findLabel r_is n_is r_lits n_lits r_ptrs n_ptrs []
= (reverse r_is, reverse r_lits, reverse r_ptrs)
mkBits findLabel r_is n_is r_lits n_lits r_ptrs n_ptrs (instr:instrs)
= case instr of
ARGCHECK n -> boring2 i_ARGCHECK n
PUSH_L sz off -> boring3 i_PUSH_L sz off
PUSH_G nm -> exciting2_P i_PUSH_G n_ptrs nm
PUSHT_I i -> exciting2_I i_PUSHT_I n_lits i
PUSHT_F f -> exciting2_F i_PUSHT_F n_lits f
PUSHT_D d -> exciting2_D i_PUSHT_D n_lits d
PUSHU_I i -> exciting2_I i_PUSHU_I n_lits i
PUSHU_F f -> exciting2_F i_PUSHU_F n_lits f
PUSHU_D d -> exciting2_D i_PUSHU_D n_lits d
SLIDE n by -> boring3 i_SLIDE n by
ALLOC n -> boring2 i_ALLOC n
MKAP off sz -> boring3 i_MKAP off sz
UNPACK n -> boring2 i_UNPACK n
PACK dcon sz -> exciting3_A i_PACK sz n_lits nullAddr {-findItbl dcon-}
LABEL lab -> nop
TESTLT_I i l -> exciting3_I i_TESTLT_I n_lits (findLabel l) i
TESTEQ_I i l -> exciting3_I i_TESTEQ_I n_lits (findLabel l) i
TESTLT_F f l -> exciting3_F i_TESTLT_F n_lits (findLabel l) f
TESTEQ_F f l -> exciting3_F i_TESTEQ_F n_lits (findLabel l) f
TESTLT_D d l -> exciting3_D i_TESTLT_D n_lits (findLabel l) d
TESTEQ_D d l -> exciting3_D i_TESTEQ_D n_lits (findLabel l) d
TESTLT_P i l -> exciting3_I i_TESTLT_P n_lits (findLabel l) i
TESTEQ_P i l -> exciting3_I i_TESTEQ_P n_lits (findLabel l) i
CASEFAIL -> boring1 i_CASEFAIL
ENTER -> boring1 i_ENTER
where
r_mkILit = reverse . mkILit
r_mkFLit = reverse . mkFLit
r_mkDLit = reverse . mkDLit
r_mkALit = reverse . mkALit
mkw :: Int -> Word16
mkw = fromIntegral
nop
= mkBits findLabel r_is n_is r_lits n_lits r_ptrs n_ptrs instrs
boring1 i1
= mkBits findLabel (mkw i1 : r_is) (n_is+1)
r_lits n_lits r_ptrs n_ptrs instrs
boring2 i1 i2
= mkBits findLabel (mkw i2 : mkw i1 : r_is) (n_is+2)
r_lits n_lits r_ptrs n_ptrs instrs
boring3 i1 i2 i3
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3)
r_lits n_lits r_ptrs n_ptrs instrs
exciting2_P i1 i2 p
= mkBits findLabel (mkw i2 : mkw i1 : r_is) (n_is+2) r_lits n_lits
(p:r_ptrs) (n_ptrs+1) instrs
exciting3_P i1 i2 i3 p
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3) r_lits n_lits
(p:r_ptrs) (n_ptrs+1) instrs
exciting2_I i1 i2 i
= mkBits findLabel (mkw i2 : mkw i1 : r_is) (n_is+2)
(r_mkILit i ++ r_lits) (n_lits + intLitSz32s)
r_ptrs n_ptrs instrs
exciting3_I i1 i2 i3 i
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3)
(r_mkILit i ++ r_lits) (n_lits + intLitSz32s)
r_ptrs n_ptrs instrs
exciting2_F i1 i2 f
= mkBits findLabel (mkw i2 : mkw i1 : r_is) (n_is+2)
(r_mkFLit f ++ r_lits) (n_lits + floatLitSz32s)
r_ptrs n_ptrs instrs
exciting3_F i1 i2 i3 f
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3)
(r_mkFLit f ++ r_lits) (n_lits + floatLitSz32s)
r_ptrs n_ptrs instrs
exciting2_D i1 i2 d
= mkBits findLabel (mkw i2 : mkw i1 : r_is) (n_is+2)
(r_mkDLit d ++ r_lits) (n_lits + doubleLitSz32s)
r_ptrs n_ptrs instrs
exciting3_D i1 i2 i3 d
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3)
(r_mkDLit d ++ r_lits) (n_lits + doubleLitSz32s)
r_ptrs n_ptrs instrs
exciting3_A i1 i2 i3 d
= mkBits findLabel (mkw i3 : mkw i2 : mkw i1 : r_is) (n_is+3)
(r_mkALit d ++ r_lits) (n_lits + addrLitSz32s)
r_ptrs n_ptrs instrs
-- The size in bytes of an instruction.
instrSizeB :: BCInstr -> Int
instrSizeB instr
= case instr of
ARGCHECK _ -> 4
PUSH_L _ _ -> 6
PUSH_G _ -> 4
PUSHT_I _ -> 4
PUSHT_F _ -> 4
PUSHT_D _ -> 4
PUSHU_I _ -> 4
PUSHU_F _ -> 4
PUSHU_D _ -> 4
SLIDE _ _ -> 6
ALLOC _ -> 4
MKAP _ _ -> 6
UNPACK _ -> 4
PACK _ _ -> 6
LABEL _ -> 4
TESTLT_I _ _ -> 6
TESTEQ_I _ _ -> 6
TESTLT_F _ _ -> 6
TESTEQ_F _ _ -> 6
TESTLT_D _ _ -> 6
TESTEQ_D _ _ -> 6
TESTLT_P _ _ -> 6
TESTEQ_P _ _ -> 6
CASEFAIL -> 2
ENTER -> 2
-- Sizes of Int, Float and Double literals, in units of 32-bitses
intLitSz32s, floatLitSz32s, doubleLitSz32s, addrLitSz32s :: Int
intLitSz32s = wORD_SIZE `div` 4
floatLitSz32s = 1 -- Assume IEEE floats
doubleLitSz32s = 2
addrLitSz32s = intLitSz32s
-- Make lists of 32-bit words for literals, so that when the
-- words are placed in memory at increasing addresses, the
-- bit pattern is correct for the host's word size and endianness.
mkILit :: Int -> [Word32]
mkFLit :: Float -> [Word32]
mkDLit :: Double -> [Word32]
mkALit :: Addr -> [Word32]
mkFLit f
= runST (do
arr <- newFloatArray ((0::Int),0)
writeFloatArray arr 0 f
w0 <- readWord32Array arr 0
return [w0]
)
mkDLit d
= runST (do
arr <- newDoubleArray ((0::Int),0)
writeDoubleArray arr 0 d
w0 <- readWord32Array arr 0
w1 <- readWord32Array arr 1
return [w0,w1]
)
mkILit i
| wORD_SIZE == 4
= runST (do
arr <- newIntArray ((0::Int),0)
writeIntArray arr 0 i
w0 <- readWord32Array arr 0
return [w0]
)
| wORD_SIZE == 8
= runST (do
arr <- newIntArray ((0::Int),0)
writeIntArray arr 0 i
w0 <- readWord32Array arr 0
w1 <- readWord32Array arr 1
return [w0,w1]
)
mkALit a
| wORD_SIZE == 4
= runST (do
arr <- newAddrArray ((0::Int),0)
writeAddrArray arr 0 a
w0 <- readWord32Array arr 0
return [w0]
)
| wORD_SIZE == 8
= runST (do
arr <- newAddrArray ((0::Int),0)
writeAddrArray arr 0 a
w0 <- readWord32Array arr 0
w1 <- readWord32Array arr 1
return [w0,w1]
)
#include "../rts/Bytecodes.h"
i_ARGCHECK = (bci_ARGCHECK :: Int)
i_PUSH_L = (bci_PUSH_L :: Int)
i_PUSH_G = (bci_PUSH_G :: Int)
i_PUSHT_I = (bci_PUSHT_I :: Int)
i_PUSHT_F = (bci_PUSHT_F :: Int)
i_PUSHT_D = (bci_PUSHT_D :: Int)
i_PUSHU_I = (bci_PUSHU_I :: Int)
i_PUSHU_F = (bci_PUSHU_F :: Int)
i_PUSHU_D = (bci_PUSHU_D :: Int)
i_SLIDE = (bci_SLIDE :: Int)
i_ALLOC = (bci_ALLOC :: Int)
i_MKAP = (bci_MKAP :: Int)
i_UNPACK = (bci_UNPACK :: Int)
i_PACK = (bci_PACK :: Int)
i_LABEL = (bci_LABEL :: Int)
i_TESTLT_I = (bci_TESTLT_I :: Int)
i_TESTEQ_I = (bci_TESTEQ_I :: Int)
i_TESTLT_F = (bci_TESTLT_F :: Int)
i_TESTEQ_F = (bci_TESTEQ_F :: Int)
i_TESTLT_D = (bci_TESTLT_D :: Int)
i_TESTEQ_D = (bci_TESTEQ_D :: Int)
i_TESTLT_P = (bci_TESTLT_P :: Int)
i_TESTEQ_P = (bci_TESTEQ_P :: Int)
i_CASEFAIL = (bci_CASEFAIL :: Int)
i_ENTER = (bci_ENTER :: Int)
\end{code}
ghc/rts/Bytecodes.h
View file @
55f6344c
/* -----------------------------------------------------------------------------
* $Id: Bytecodes.h,v 1.1
7 2000/10/09 11:20:16 daan
Exp $
* $Id: Bytecodes.h,v 1.1
8 2000/12/06 15:23:31 sewardj
Exp $
*
* (c) The GHC Team, 1998-1999
*
...
...
@@ -12,481 +12,44 @@
* Instructions
*
* Notes:
* o INTERNAL_ERROR is never generated by the compiler and usually
* indicates an error in the heap.
* PANIC is generated by the compiler whenever it tests an "irrefutable"
* o CASEFAIL is generated by the compiler whenever it tests an "irrefutable"
* pattern which fails. If we don't see too many of these, we could
* optimise out the redundant test.
*
* o If you add any new instructions, you have to check that each enumeration
* has at most 256 entries in it --- some of the lists are very close to
* overflowing.
* ------------------------------------------------------------------------*/
#define INSTRLIST \
Ins(i_INTERNAL_ERROR), \
Ins(i_PANIC), \
Ins(i_STK_CHECK), \
Ins(i_STK_CHECK_big), \
Ins(i_ARG_CHECK), \
Ins(i_ALLOC_AP), \
Ins(i_ALLOC_PAP), \
Ins(i_ALLOC_CONSTR), \
Ins(i_ALLOC_CONSTR_big), \
Ins(i_MKAP), \
Ins(i_MKAP_big), \
Ins(i_MKPAP), \
Ins(i_PACK), \
Ins(i_PACK_big), \
Ins(i_SLIDE), \
Ins(i_SLIDE_big), \
Ins(i_TEST), \
Ins(i_UNPACK), \
Ins(i_VAR), \
Ins(i_VAR_big), \
Ins(i_CONST), \
Ins(i_CONST_big), \
Ins(i_ENTER), \
Ins(i_RETADDR), \
Ins(i_RETADDR_big), \
Ins(i_VOID), \
\
Ins(i_ALLOC_ROW), \
Ins(i_ALLOC_ROW_big), \
Ins(i_PACK_ROW), \
Ins(i_PACK_ROW_big), \
Ins(i_UNPACK_ROW), \
Ins(i_CONST_ROW_TRIV), \
\
Ins(i_PACK_INJ), \
Ins(i_PACK_INJ_VAR), \
Ins(i_PACK_INJ_VAR_big), \
Ins(i_PACK_INJ_CONST_8), \
Ins(i_PACK_INJ_REL_8), \
Ins(i_TEST_INJ), \
Ins(i_TEST_INJ_VAR), \
Ins(i_TEST_INJ_VAR_big), \
Ins(i_TEST_INJ_CONST_8), \
Ins(i_TEST_INJ_REL_8), \
Ins(i_UNPACK_INJ), \
Ins(i_CONST_WORD_8), \
Ins(i_ADD_WORD_VAR), \
Ins(i_ADD_WORD_VAR_big), \
Ins(i_ADD_WORD_VAR_8), \
\
Ins(i_VAR_INT), \
Ins(i_VAR_INT_big), \
Ins(i_CONST_INT), \
Ins(i_CONST_INT_big), \
Ins(i_PACK_INT), \
Ins(i_UNPACK_INT), \
Ins(i_TEST_INT), \
Ins(i_CONST_INTEGER), \
Ins(i_CONST_INTEGER_big), \
Ins(i_VAR_WORD), \
Ins(i_VAR_WORD_big), \
Ins(i_CONST_WORD), \
Ins(i_CONST_WORD_big), \
Ins(i_PACK_WORD), \
Ins(i_UNPACK_WORD), \
Ins(i_VAR_ADDR), \
Ins(i_VAR_ADDR_big), \
Ins(i_CONST_ADDR), \
Ins(i_CONST_ADDR_big), \
Ins(i_PACK_ADDR), \
Ins(i_UNPACK_ADDR), \
Ins(i_VAR_CHAR), \
Ins(i_VAR_CHAR_big), \
Ins(i_CONST_CHAR), \
Ins(i_CONST_CHAR_big), \
Ins(i_PACK_CHAR), \
Ins(i_UNPACK_CHAR), \
Ins(i_VAR_FLOAT), \
Ins(i_VAR_FLOAT_big), \
Ins(i_CONST_FLOAT), \
Ins(i_CONST_FLOAT_big), \
Ins(i_PACK_FLOAT), \
Ins(i_UNPACK_FLOAT), \
Ins(i_VAR_DOUBLE), \
Ins(i_VAR_DOUBLE_big), \
Ins(i_CONST_DOUBLE), \
Ins(i_CONST_DOUBLE_big), \
Ins(i_PACK_DOUBLE), \
Ins(i_UNPACK_DOUBLE), \
Ins(i_VAR_STABLE), \
Ins(i_VAR_STABLE_big), \
Ins(i_PACK_STABLE), \
Ins(i_UNPACK_STABLE), \
Ins(i_PRIMOP1), \
Ins(i_PRIMOP2), \
Ins(i_RV), \
Ins(i_RVE), \
Ins(i_SE), \
Ins(i_VV)
#define BIGGEST_OPCODE ((int)(i_VV))
#define Ins(x) x
typedef
enum
{
INSTRLIST
}
Instr
;
#undef Ins
typedef
enum
{
i_INTERNAL_ERROR1
/* Instruction 0 raises an internal error */
,
i_pushseqframe
,
i_pushcatchframe
/* Char# operations */
,
i_gtChar
,
i_geChar
,
i_eqChar
,
i_neChar
,
i_ltChar
,
i_leChar
,
i_charToInt
,
i_intToChar
/* Int# operations */
,
i_gtInt
,
i_geInt
,
i_eqInt
,
i_neInt
,
i_ltInt
,
i_leInt
,
i_minInt
,
i_maxInt