Cmm syntax
The GHC has three different syntaxes for Cmm:
- Hand-writing syntax by
GHC/Cmm/Parser.y
(e.g.PrimOps.cmm
) - Pretty-printing syntax by
GHC/Cmm/Ppr.hs
(asghc --ddump-cmm
) - Intermediate representation in
GHC/Cmm.hs
To improve readability of Cmm files, this page shows the hand-writing syntax defined by GHC/Cmm/Parser.y
.
See Code Generator and The Runtime System.
See also cmm-type.
Cmm hand-writing syntax
Following syntax was manually extracted from GHC/Cmm/Parser.y
at commit 5618fc21.
cmm → {- empty -}
| cmmtop cmm
cmmtop → cmmproc
| cmmdata
| decl
| 'CLOSURE' '(' NAME ',' NAME lits ')' ';'
cmmdata → 'section' STRING '{' data_label statics '}'
data_label → NAME ':'
statics → {- empty -}
| static statics
static → type expr ';'
| type ';'
| 'bits8' '[' ']' STRING ';'
| 'bits8' '[' INT ']' ';'
| typenot8 '[' INT ']' ';'
| 'CLOSURE' '(' NAME lits ')'
lits → {- empty -}
| ',' expr lits
cmmproc → info maybe_conv maybe_formals maybe_body
maybe_conv → {- empty -}
| 'return'
maybe_body → ';'
| '{' body '}'
info → NAME
| 'INFO_TABLE' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ')'
| 'INFO_TABLE_FUN' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ',' INT ',' INT ')'
| 'INFO_TABLE_CONSTR' '(' NAME ',' INT ',' INT ',' INT ',' INT ',' STRING ',' STRING ')'
| 'INFO_TABLE_SELECTOR' '(' NAME ',' INT ',' INT ',' STRING ',' STRING ')'
| 'INFO_TABLE_RET' '(' NAME ',' INT ')'
| 'INFO_TABLE_RET' '(' NAME ',' INT ',' formals0 ')'
body → {- empty -}
| decl body
| stmt body
decl → type names ';'
| 'import' importNames ';'
| 'export' names ';'
importNames → importName
| importName ',' importNames
importName → NAME
| 'CLOSURE' NAME
| STRING NAME
names → NAME
| NAME ',' names
stmt → ';'
| NAME ':'
| lreg '=' expr ';'
| lreg '=' mem_ordering type '[' expr ']' ';'
| mem_ordering type '[' expr ']' '=' expr ';'
| type '[' expr ']' '=' expr ';'
| foreign_results 'foreign' STRING foreignLabel '(' cmm_hint_exprs0 ')' safety opt_never_returns ';'
| foreign_results 'prim' '%' NAME '(' exprs0 ')' ';'
| NAME '(' exprs0 ')' ';'
| 'switch' maybe_range expr '{' arms default '}'
| 'goto' NAME ';'
| 'return' '(' exprs0 ')' ';'
| 'jump' expr vols ';'
| 'jump' expr '(' exprs0 ')' ';'
| 'jump' expr '(' exprs0 ')' '(' exprs0 ')' ';'
| 'call' expr '(' exprs0 ')' ';'
| '(' formals ')' '=' 'call' expr '(' exprs0 ')' ';'
| 'if' bool_expr cond_likely 'goto' NAME
| 'if' bool_expr cond_likely '{' body '}' else
| 'push' '(' exprs0 ')' maybe_body
| 'reserve' expr '=' lreg maybe_body
| 'unwind' unwind_regs ';'
unwind_regs → GLOBALREG '=' expr_or_unknown ',' unwind_regs
| GLOBALREG '=' expr_or_unknown
mem_ordering → 'relaxed'
| 'release'
| 'acquire'
| 'seq_cst'
expr_or_unknown → 'return'
| expr
foreignLabel → NAME
opt_never_returns → {- empty -}
| 'never' 'returns'
bool_expr → bool_op
| expr
bool_op → bool_expr '&&' bool_expr
| bool_expr '||' bool_expr
| '!' bool_expr
| '(' bool_op ')'
safety → {- empty -}
| STRING
vols → '[' ']'
| '[' '*' ']'
| '[' globals ']'
globals → GLOBALREG
| GLOBALREG ',' globals
maybe_range → '[' INT '..' INT ']'
| {- empty -}
arms → {- empty -}
| arm arms
arm → 'case' ints ':' arm_body
arm_body → '{' body '}'
| 'goto' NAME ';'
ints → INT
| INT ',' ints
default → 'default' ':' '{' body '}'
| {- empty -}
else → {- empty -}
| 'else' '{' body '}'
cond_likely → '(' 'likely' ':' 'True' ')'
| '(' 'likely' ':' 'False' ')'
| {- empty -}
expr → expr '/' expr
| expr '*' expr
| expr '%' expr
| expr '-' expr
| expr '+' expr
| expr '>>' expr
| expr '<<' expr
| expr '&' expr
| expr '^' expr
| expr '|' expr
| expr '>=' expr
| expr '>' expr
| expr '<=' expr
| expr '<' expr
| expr '!=' expr
| expr '==' expr
| '~' expr
| '-' expr
| expr0 '`' NAME '`' expr0
| expr0
expr0 → INT maybe_ty
| FLOAT maybe_ty
| STRING
| reg
| type dereference
| '%' NAME '(' exprs0 ')'
| '(' expr ')'
dereference → '^' '[' expr ']'
| '[' expr ']'
maybe_ty → {- empty -}
| '::' type
cmm_hint_exprs0 → {- empty -}
| cmm_hint_exprs
cmm_hint_exprs → cmm_hint_expr
| cmm_hint_expr ',' cmm_hint_exprs
cmm_hint_expr → expr
| expr STRING
exprs0 → {- empty -}
| exprs
exprs → expr
| expr ',' exprs
reg → NAME
| GLOBALREG
foreign_results → {- empty -}
| '(' foreign_formals ')' '='
foreign_formals → foreign_formal
| foreign_formal ','
| foreign_formal ',' foreign_formals
foreign_formal → local_lreg
| STRING local_lreg
local_lreg → NAME
lreg → NAME
| GLOBALREG
maybe_formals → {- empty -}
| '(' formals0 ')'
formals0 → {- empty -}
| formals
formals → formal ','
| formal
| formal ',' formals
formal → type NAME
type → 'bits8'
| typenot8
typenot8 → 'bits16'
| 'bits32'
| 'bits64'
| 'bits128'
| 'bits256'
| 'bits512'
| 'float32'
| 'float64'
| 'gcptr'
See also GHC/Cmm/Lexer.x
for lexical tokens. For instance:
GLOBALREG → P@decimal
R@decimal
F@decimal
D@decimal
L@decimal
Sp
SpLim
Hp
HpLim
CCCS
CurrentTSO
CurrentNursery
HpAlloc
BaseReg
MachSp
UnwindReturnReg
Built-in macros and primitives
Some built-in macros and primitives are defined for Cmm hand-writing syntax in GHC/Cmm/Parser.y
.
Built-in expression macros (exprMacros):
%ENTRY_CODE
%INFO_PTR
%STD_INFO
%FUN_INFO
%GET_ENTRY
%GET_STD_INFO
%GET_FUN_INFO
%INFO_TYPE
%INFO_PTRS
%INFO_NPTRS
Built-in primitives (machOps):
%add
%sub
%eq
%ne
%mul
%mulmayoflo
%neg
%quot
%rem
%divu
%modu
%ge
%le
%gt
%lt
%geu
%leu
%gtu
%ltu
%and
%or
%xor
%com
%shl
%shrl
%shra
%fadd
%fsub
%fneg
%fmul
%fquot
%feq
%fne
%fge
%fle
%fgt
%flt
%lobits8
%lobits16
%lobits32
%lobits64
%zx16
%zx32
%zx64
%sx16
%sx32
%sx64
%f2f32
%f2f64
%f2i8
%f2i16
%f2i32
%f2i64
%i2f32
%i2f64
Built-in callish primitives (callishMachOps):
%pow64f
%sin64f
%cos64f
%tan64f
%sinh64f
%cosh64f
%tanh64f
%asin64f
%acos64f
%atan64f
%asinh64f
%acosh64f
%log64f
%log1p64f
%exp64f
%expM164f
%fabs64f
%sqrt64f
%pow32f
%sin32f
%cos32f
%tan32f
%sinh32f
%cosh32f
%tanh32f
%asin32f
%acos32f
%atan32f
%asinh32f
%acosh32f
%log32f
%log1p32f
%exp32f
%expM132f
%fabs32f
%sqrt32f
%read_barrier
%write_barrier
%memcpy
%memset
%memmove
%memcmp
%suspendThread
%resumeThread
%prefetch0
%prefetch1
%prefetch2
%prefetch3
%popcnt
%pdep
%pext
%cmpxchg
%xchg
%load_relaxed
%load_acquire
%load_seqcst
%store_release
%store_seqcst
Built-in statement macros (stmtMacros):
CCS_ALLOC
ENTER_CCS_THUNK
CLOSE_NURSERY
OPEN_NURSERY
HP_CHK_GEN
STK_CHK_GEN
STK_CHK_GEN_N
LOAD_THREAD_STATE
SAVE_THREAD_STATE
SAVE_REGS
RESTORE_REGS
PUSH_ARG_REGS
POP_ARG_REGS
LDV_ENTER
LDV_RECORD_CREATE
PUSH_UPD_FRAME
SET_HDR
TICK_ALLOC_PRIM
TICK_ALLOC_PAP
TICK_ALLOC_UP_THK
UPD_BH_UPDATABLE
C-preprocessor macros
There are also C-preprocessor level macros, such as ccall
, I64
, Sp(n)
, LOAD_INFO
, ENTER(x)
, and MAYBE_GC
.
Those macros are defined in includes/Cmm.h
.