[Git][ghc/ghc][wip/ghci-primcall] finish documentation on call_info word and some minor cleanups
Luite Stegeman (@luite)
gitlab at gitlab.haskell.org
Sun Jan 8 14:26:58 UTC 2023
Luite Stegeman pushed to branch wip/ghci-primcall at Glasgow Haskell Compiler / GHC
Commits:
ae1dfed9 by Luite Stegeman at 2023-01-08T23:26:20+09:00
finish documentation on call_info word and some minor cleanups
- - - - -
4 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/Cmm/CallConv.hs
- compiler/GHC/StgToByteCode.hs
- rts/StgMiscClosures.cmm
Changes:
=====================================
compiler/GHC/ByteCode/Asm.hs
=====================================
@@ -600,7 +600,7 @@ maxPrimCallNativeStackSize = 255
mkNativeCallInfoSig :: Platform -> NativeCallInfo -> Word32
mkNativeCallInfoSig platform NativeCallInfo{..}
| nativeCallType == NativePrimCall && nativeCallStackSpillSize > maxPrimCallNativeStackSize
- = pprPanic "mkNativeCallInfoSig: call too big for the bytecode compiler"
+ = pprPanic "mkNativeCallInfoSig: native call too big for the bytecode compiler"
(ppr nativeCallStackSpillSize <+> text "stack words." <+>
text "Use -fobject-code to get around this limit"
)
=====================================
compiler/GHC/Cmm/CallConv.hs
=====================================
@@ -224,7 +224,7 @@ realArgRegsCover platform
{-
Note [GHCi and native call registers]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The GHCi bytecode interpreter does not have access to the STG registers
that the native calling convention uses for passing arguments. It uses
@@ -233,7 +233,7 @@ realArgRegsCover platform
If only a single register needs to be moved, GHCi uses a specific stack
frame. For example stg_ctoi_R1p saves a heap pointer value from STG register
R1 and stg_ctoi_D1 saves a double precision floating point value from D1.
- In the other directin, helpers stg_ret_p and stg_ret_d move a value from
+ In the other direction, helpers stg_ret_p and stg_ret_d move a value from
the stack to the R1 and D1 registers, respectively.
When GHCi needs to move more than one register it cannot use a specific
@@ -243,22 +243,73 @@ realArgRegsCover platform
and the number of stack words used by the arguments of a call.
These helper stack frames are currently:
+
- stg_ret_t: return a tuple to the continuation at the top of
the stack
- - stg_ctoi_t: convert a tuple value to be used in bytecode
+ - stg_ctoi_t: convert a tuple return value to be used in
+ bytecode
- stg_primcall: call a function
- The call_info word XXX incomplete!!!
- XXX TODO
+ The call_info word contains a bitmap of the active registers
+ for the call and and a stack offset. The layout is as follows:
+
+ - bit 0-23: Bitmap of active registers for the call, the
+ order corresponds to the list returned by
+ allArgRegsCover. For example if bit 0 (the least
+ significant bit) is set, the first register in the
+ allArgRegsCover list is active. Bit 1 for the
+ second register in the list and so on.
+
+ - bit 24-31: Unsigned byte, indicating the stack usage of the
+ call in words (not counting the space )
+
+ The upper 32 bits on 64 bit platforms are currently unused.
+
+ If a register is smaller than a word on the stack (for example a
+ single precision float on a 64 bit system), then the stack slot
+ is padded to a whole word.
+
+ Example:
+
+ If a call has three arguments passed registers and and
+ additional five words of arguments on the stack, then
+ three bits in the bitmap in bits 0-23 would be set. And
+ Bit 24-31 would be 00000010 (two in binary).
+
+ The values on the stack before a call to POP_ARG_REGS would
+ be as follows:
+
+ ...
+ stack_arg_1
+ stack_arg_2
+ register_arg_3
+ register_arg_2
+ register_arg_1 <- Sp
+
+ A call to POP_ARG_REGS(call_info) would move register_arg_1
+ to the register corresponding to the lowest set bit in the
+ call_info word. register_arg_2 would be moved to the register
+ corresponding to the second lowest set bit, and so on.
- XXX TODO
+ After POP_ARG_REGS(call_info), the stack pointer Sp points
+ to the first stack slot below the stack arguments. The stack
+ arguments are still on the stack above Sp, so the stack looks
+ as follows:
- XXX TODO
+ ... <- Sp
+ stack_arg_1
+ stack_arg_2
- XXX TODO
+ At this point all the arguments are in place and we are ready
+ to jump to the native function.
- XXX TODO
+ On x86_64, the double precision (Dn) and single precision
+ floating (Fn) point registers overlap, e.g. D1 uses the same
+ physical register as F1. On this platform, the list returned
+ by allArgRegsCover contains only entries for the double
+ precision registers. If an argument is passed in register
+ Fn, the bit corresponding to Dn should be set.
Note: if anything changes in how registers for native calls overlap,
make sure to also update GHC.StgToByteCode.layoutNativeCall
=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -1250,7 +1250,6 @@ tupleBCO platform info pointers =
body_code = mkSlideW 0 1 -- pop frame header
`snocOL` RETURN_TUPLE -- and add it again
--- XXX merge with tupleBCO
primCallBCO :: Platform -> NativeCallInfo -> [(Bool, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
primCallBCO platform args_info pointers =
mkProtoBCO platform invented_name body_code (Left [])
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -366,20 +366,10 @@ MK_STG_CTOI_T(61)
MK_STG_CTOI_T(62)
/*
- Note [GHCi tuple layout]
- ~~~~~~~~~~~~~~~~~~~~~~~~
- the tuple_info word describes the register and stack usage of the tuple:
+ Convert a tuple return value to be used in bytecode.
- [ ssss ssss rrrr rrrr rrrr rrrr rrrr rrrr ]
-
- - r: bitmap of live registers, corresponding to the list of registers
- returned by GHC.Cmm.CallConv.tupleRegsCover (the least significant
- bit corresponds to the first element in the list)
- - s: number of words on stack (in addition to registers)
-
- The order of the live registers in the bitmap is the same as the list
- given by GHC.Cmm.CallConv.tupleRegsCover, with the least significant
- bit corresponding to the first register in the list.
+ See Note [GHCi and native call registers] for information on how
+ values are moved between the stack and registers.
*/
stg_ctoi_t
@@ -433,13 +423,9 @@ INFO_TABLE_RET( stg_ret_t, RET_BCO )
/*
The stg_primcall frame is used by the bytecode interpreter to call
- a Cmm function. The frame contains an args_info word that contains
+ a Cmm function. The frame contains a call_info word that contains
a bitmap describing the register arguments.
- The register arguments are moved to registers first (they are on
- the stack in the order that POP_ARG_REGS expects) while the
- remaining arguments are left on the stack.
-
When the target function is called, Sp points to the topmost stack
argument.
@@ -450,11 +436,13 @@ INFO_TABLE_RET( stg_ret_t, RET_BCO )
...
arg_n
target_funptr (pointer to the function we're calling)
- args_info (describes the registers containing the arguments)
+ call_info (describes the registers containing the arguments)
primcall_BCO (contains bitmap describing pointers in args)
stg_primcall_info <- Sp
- - XXX describe register bitmaps
+ See Note [GHCi and native call registers] for information on the call_info
+ word and how registers are moved between the stack and registers.
+
*/
INFO_TABLE_RET ( stg_primcall, RET_BCO )
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae1dfed92faca6dc7fead5a14c524701a2167f17
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae1dfed92faca6dc7fead5a14c524701a2167f17
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230108/ac460935/attachment-0001.html>
More information about the ghc-commits
mailing list