I've spotted a likely candidate for the mcode stack
problem while looking through the debug instruction
output from the back end.
I have not yet verified that the emitted binary code
has the duplicated Emit_Call's shown below, but if they
are there, then this could very well be causing the weird
stack-alignment-dependent crashes.
I also have not looked into what is causing these
doubled-up calls to be generated, nor for any other
side effects caused by this two-for-one special.
Detail:
In the 0.29.1 debug output below, note that 'Setup_Frame'
is followed by duplicate, back-to-back, 'call's.
( also see end of message for 0.25 vs. 0.29.1 output )
" Setup_Frame
" push (fp,-16 {INSTANCE})
" call:Nil work__tristate_bug__ARCH__crashes__ELAB
" call:Nil work__tristate_bug__ARCH__crashes__ELAB
Looking at the call support routines in
<ortho\mcode\ortho_code-x86-emits.adb>
Emit_Setup_Frame:
if Get_Subprg_Stack space required is not aligned
on Flags.Stack_Boundary, pad stack as needed
Emit_Call:
- Gen_Call calls the subprogram
- Cleanup stack
Val = Get_Subprg_Stack + alignment padding
addl esp,Val
So, if Emit_Call is ever invoked __without__ a preceding
Emit_Setup_Frame, Bad Things will happen whenever the
Emit_Call cleanup code attempts to remove stack alignment
padding that is not actually there.
Whether the stack actually gets padded so as to expose
this problem is dependent on the stack alignment settings,
current stack alignment, number of args, etc.
Brian
Example debug output snippet from GHDL 0.25
command line:
ghdl -r --be-debug=i --workdir=work.ghd tristate_bug
-----------
1214 public procedure __ghdl_ELABORATE
# block start
1216 block until 1218
1217 local ARCH_INSTANCE: 1102, offset=-12
1218 local INSTANCE: 1094, offset=-16
push [00000010]
reg_7{ax } = call:P32 __ghdl_malloc0
assign:P32 (fp,-12 {ARCH_INSTANCE}) <- reg_7{ax }
reg_12{ax } = indir:P32 (fp,-12 {ARCH_INSTANCE})
assign:P32 (fp,-16 {INSTANCE}) <- reg_12{ax }
reg_20{ax } = indir:P32 (fp,-16 {INSTANCE})
assign:P32 (reg_20{ax } + [00000004]) <- [00000000]
reg_27{ax } = indir:P32 (fp,-12 {ARCH_INSTANCE})
assign:P32 (&__ghdl_rti_top_instance) <- reg_27{ax }
assign:P32 (&__ghdl_rti_top_ptr) <- &__ghdl_rti_top
push (fp,-16 {INSTANCE})
call:Nil work__tristate_bug__ARCH__crashes__ELAB
push (fp,-12 {ARCH_INSTANCE})
call:Nil work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
# block end
L3:
leave
-----------
Example debug output snippet from GHDL 0.29.1 patched
-----
<ortho\mcode\ortho_code-x86-abi.adb>
+ when OE_Setup_Frame =>
+ Put_Line (" Setup_Frame");
when OE_Call =>
if Get_Expr_Mode (Stmt) /= Mode_Nil then
-----
command line:
ghdl -r --be-debug=i --workdir=work.ghd tristate_bug
-----------
1249 public procedure __ghdl_ELABORATE
# block start
1251 block until 1253
1252 local ARCH_INSTANCE: 1106, offset=-12
1253 local INSTANCE: 1098, offset=-16
Setup_Frame
push [00000012]
reg_7{ax } = call:P32 __ghdl_malloc0
assign:P32 (fp,-12 {ARCH_INSTANCE}) <- reg_7{ax }
reg_12{ax } = indir:P32 (fp,-12 {ARCH_INSTANCE})
assign:P32 (fp,-16 {INSTANCE}) <- reg_12{ax }
reg_20{ax } = indir:P32 (fp,-16 {INSTANCE})
assign:P32 (reg_20{ax } + [00000004]) <- [00000000]
reg_27{ax } = indir:P32 (fp,-12 {ARCH_INSTANCE})
assign:P32 (&__ghdl_rti_top_instance) <- reg_27{ax }
assign:P32 (&__ghdl_rti_top_ptr) <- &__ghdl_rti_top
Setup_Frame
push (fp,-16 {INSTANCE})
call:Nil work__tristate_bug__ARCH__crashes__ELAB
call:Nil work__tristate_bug__ARCH__crashes__ELAB
Setup_Frame
push (fp,-12 {ARCH_INSTANCE})
call:Nil work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
call:Nil work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
# block end
L3:
leave
-----------
_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss