cgdoc.gml

来自「开放源码的编译器open watcom 1.6.0版的源代码」· GML 代码 · 共 2,235 行 · 第 1/5 页

GML
2,235
字号
:INCLUDE file='LYTCHG'.
:INCLUDE file='FMTMACRO'.
:INCLUDE file='GMLMACS'.
:INCLUDE file='XDEFS'.
:INCLUDE file='DEFS'.
.*
:GDOC.
.*
.if &e'&dohelp eq 0 .do begin
:FRONTM.
:TITLEP.
:TITLE.&company Code Generator Interface
:cmt. :DATE.
:eTITLEP.
:TOC.
.do end
.*
:BODY.
.*
:cmt. index is disabled
.if &e'&dohelp eq 2 .do begin
:exhelp
:include file='&book..idx'
:include file='&book..tbl'
:include file='&book..kw'
.do end
.chap General
:P.The code generator (back end) interface is a set of procedure calls.
These are divided into Code Generation (CG), Data Generation (DG),
miscellaneous Back End (BE), Front end supplied (FE), and debugger
information (DB) routines.
.section cg_init_info BEInit( cg_switches switches, cg_target_switches targ_switches, uint optsize, proc_revision proc )
:I1.BEInit
:P.Initialize the code generator.
This must be the first routine to be called.
:DL.
:DTHD.Parameter
:DDHD.Definition
:DT.switches
:DD.Select code generation options.
The options are bits, so may be combined with the bit-wise operator |.
Options apply to the entire compilation unit.
The bit values are defined below.
:DT.targ_switches
:DD.Target specific switches.
The bit values are defined below.
:DT.optsize
:DD.A number between 0 and 100.
0 means optimize for speed, 100 means optimize for size.
Anything in between selects a compromise between speed and size.
:DT.proc
:DD.The target hardware configuration, defined below.
:eDL.
:DL.
:DT.Returns
:DD.Information about the code generator revision in a cg_init_info
structure, defined below.
:eDL.
:DL tsize='2i' break.
:I1.options
:DTHD.Switch
:DDHD.Definition
:DT.NO_OPTIMIZATION
:DD.Turn off optimizations.
:DT.NUMBERS
:DD.Generate line number debugging information.
:DT.FORTRAN_ALIASING
:DD.Assume pointers are only used for parameter passing.
:DT.DBG_DF
:DD.Generate debugging information in DWARF format.
:DT.DBG_CV
:DD.Generate debugging information in CodeView format. If neither
DBG_DF nor DBG_CV is set, debugging information (if any) is
generated in the Watcom format.
:DT.RELAX_ALIAS
:DD.Assume that a static/extern variable and a pointer to that same
variable are not used within the same routine.
:DT.DBG_LOCALS
:DD.Generate local symbol information for use by a debugger.
:DT.DBG_TYPES
:DD.Generate typing information for use by a debugger.
:DT.LOOP_UNROLLING
:DD.Turn on loop unrolling.
:DT.LOOP_OPTIMIZATION
:DD.Turn on loop optimizations.
:DT.INS_SCHEDULING
:DD.Turn on instruction scheduling.
:DT.MEMORY_LOW_FAILS
:DD.Allow the code generator to run out of memory without being able to
generate object code (allows the 386 compiler to use EBP as a cache
register).
:DT.FP_UNSTABLE_OPTIMIZATION
:DD.Allow the code generator to perform optimizations that are
mathematically correct, but are numerically unstable.
E.g.
converting division by a constant to a multiplication by the reciprocal.
:DT.NULL_DEREF_OK
:DD.NULL points to valid memory and may be dereferenced.
:DT.FPU_ROUNDING_INLINE
:DD.Inline floating-point value rounding (actually truncation) routine
when converting floating-point values to integers.
:DT.FPU_ROUNDING_OMIT
:DD.Omit floating-point value rounding entirely and use FPU default. Results
will not be ISO C compliant.
:DT.ECHO_API_CALLS
:DD.Log each call to the code generator with its arguments and return value.
Only available in debug builds.
:DT.OBJ_ELF
:DD.Emit ELF object files.
:DT.OBJ_COFF
:DD.Emit COFF object files. For Intel compilers, OMF object files will
be emitted in the absence of either switch.
:DT.OBJ_ENDIAN_BIG
:DD.Emit big-endian object files (COFF or ELF). If OBJ_ENDIAN_BIG is not
set, little-endian objects will be generated.
:eDL.
:DL tsize='2i' break.
:DTHD.x86 Switch
:DDHD.Definition
:DT.I_MATH_INLINE
:DD.Do not check arguments for operators like O_SQRT.
This allows the compiler to use some specialty x87 instructions.
:DT.EZ_OMF
:DD.Generate Phar Lap EZ-OMF object files.
:DT.BIG_DATA
:DD.Use segmented pointers (16:16 or 16:32).
This defines T_POINTER to be equivalent to T_HUGE_POINTER.
:DT.BIG_CODE
:DD.Use inter segment (far) call and return instructions.
:DT.CHEAP_POINTER
:DD.Assume far objects are addressable by one segment value.
This must be used in conjunction with BIG_DATA.
It defines T_POINTER to be equivalent to T_FAR_POINTER.
:DT.FLAT_MODEL
:DD.Assume all segment registers address the same base memory.
:DT.FLOATING_FS
:DD.Does FS float (or is it pegged to DGROUP).
:DT.FLOATING_GS
:DD.Does GS float (or is it pegged to DGROUP).
:DT.FLOATING_ES
:DD.Does ES float (or is it pegged to DGROUP).
:DT.FLOATING_SS
:DD.Does SS float (or is it pegged to DGROUP).
:DT.FLOATING_DS
:DD.Does DS float (or is it pegged to DGROUP).
:DT.USE_32
:DD.Generate code into a use32 segment (versus use16).
:DT.INDEXED_GLOBALS
:DD.Generate all global and static variable references as an offset
past EBX.
:DT.WINDOWS
:DD.Generate windows prolog/epilog sequences for all routines.
:DT.CHEAP_WINDOWS
:DD.Generate windows prolog/epilog sequences assuming that call backs
functions are defined as __export.
:DT.NO_CALL_RET_TRANSFORM
:DD.Do not change a CALL followed by a RET into a JMP.
This is used for some older overlay managers that cannot handle a JMP
to an overlay.
:DT.CONST_IN_CODE
:DD.Generate all constant data into the code segment.
This only applies to the internal code generator data, such as floating
point constants.
The front end decides where its data goes using BESetSeg().
:DT.NEED_STACK_FRAME
:DD.Generate a traceable stack frame.
The first instructions will be :HP2.INC BP:eHP2. if the routine uses a
far return instruction, followed by :HP2.PUSH BP:eHP2. and :HP2.MOV
BP,SP:eHP2..
(ESP and EBP for 386 targets).
:DT.LOAD_DS_DIRECTLY
:DD.Generate code to load DS directly. By default, a call to __GETDS routine
is generated.
:DT.GEN_FWAIT_386
:DD.Generate FWAIT instructions on 386 and later CPUs. The 386 never needs
FWAIT for data synchronization, but FWAIT may still be needed for accurate
exception reporting.
:eDL.
:DL tsize='2i'.
:DTHD.RISC Switch
:DDHD.Definition
:DT.ASM_OUTPUT
:DD.Print final pseudo-assembly on the console. Debug builds only.
:DT.OWL_LOGGING
:DD.Log calls to the Object Writer Library
:DT.STACK_INIT
:DD.Pre-initialize stack variables to a known bit pattern.
:DT.EXCEPT_FILTER_USED
:DD.Set when SEH (Structured Exception Handling) is used.
:eDL
:cmt. S/370 not maintained
.if 0 eq 1 .do begin
:DL tsize='2i'.
:DTHD.370 Switch
:DDHD.Definition
:DT.BIG_DATA
:DD.???
:DT.BIG_CODE
:DD.???
:DT.FLOATING_SS
:DD.???
:DT.ASM_OUTPUT
:DD.???
:DT.CHEAP_POINTER
:DD.???
:DT.AMODE_24
:DD.???
:DT.AMODE_31
:DD.???
:DT.RMODE_24
:DD.???
:DT.CODE_RENT
:DD.???
:DT.CODE_SPLIT
:DD.???
:DT.STACK_CHECK
:DD.???
:DT.ASM_SOURCE
:DD.???
:DT.ASM_LISTING
:DD.???
:DT.NO_ZERO_INIT
:DD.???
:DT.I_MATH_INLINE
:DD.???
:eDL.
.do end
:I1.options
:P.The supported proc_revision CPU values are:
:SL.
:LI.CPU_86
:LI.CPU_186
:LI.CPU_286
:LI.CPU_386
:LI.CPU_486
:LI.CPU_586
:eSL.
:P.The supported proc_revision FPU values are:
:SL.
:LI.FPU_NONE
:LI.FPU_87
:LI.FPU_387
:LI.FPU_586
:LI.FPU_EMU
:LI.FPU_E87
:LI.FPU_E387
:LI.FPU_E586
:eSL.
:P.The supported proc_revision WEITEK values are:
:SL.
:LI.WTK_NONE
:LI.WTK_1167
:LI.WTK_3167
:LI.WTK_4167
:eSL.
:P.The following example sets the processor revision information to
indicate a 386 with 387 and Weitek 3167.
:XMP.
proc_revision proc;

SET_CPU( p, CPU_386 );
SET_FPU( p, FPU_387 );
SET_WTK( p, WTK_3167 );
:eXMP.
:P.The return value structure is defined as follows:
:XMP.
typedef union   cg_init_info {
  struct {
    unsigned revision   : 10; /* contains II_REVISION */
    unsigned target     : 5;  /* has II_TARG_??? */
    unsigned is_large   : 1;  /* 1 if 16 bit host */
  } version;
  int     success;
} cg_init_info;

enum {
  II_TARG_8086,
  II_TARG_80386,
  II_TARG_STUB,
  II_TARG_CHECK,
  II_TARG_370,
  II_TARG_AXP,
  II_TARG_PPC,
  II_TARG_MIPS
};
:eXMP.
.section void BEStart()
:I1.BEStart
:P.Start the code generator.
Must be called immediately after all calls to BEDefSeg have been made.
This restriction is relaxed somewhat for the 80(x)86 code generator.
See BEDefSeg for details.
.section void BEStop()
:I1.BEStop
:P.Normal termination of code generator.
This must be the second last routine called.
.section void BEAbort()
:I1.BEAbort
:P.Abnormal termination of code generator.
This must be the second last routine called.
.section void BEFini()
:I1.BEFini
:P.Finalize the code generator.
This must be the last routine called.
.section extern patch_handle BEPatch()
:P.Allocate a patch handle which can be used to create a patchable
integer (an integer which will have a constant value provided sometime
while the codegen is handling the CGDone call).
See CGPatchNode.
.section extern void BEPatchInteger( patch_handle hdl, signed_32 value )
:P.Patch the integer corresponding to the given handle to have the
given value.
This may be called repeatedly with different values, providing
CGPatchNode has been called and BEFiniPatch has not been called.
:DL.
:DTHD.Parameter
:DDHD.Definition
:DT.hdl
:DD.A patch_handle returned from an earlier invocation of BEPatch which
has had a node allocated for it via CGPatchNode.
If CGPatchNode has not been called with the handle given, the behaviour
is undefined.
:DT.value
:DD.A signed 32-bit integer value.
This will be the new value of the node which has been associated with
the patch handle.
:eDL.
.section extern cg_name BEFiniPatch( patch_handle hdl )
:P.This must be called to free up resources used by the given handle.
After this, the handle must not be used again.
.chap Segments
:P.The object file produced by the code generator is composed of
various segments.
These are defined by the front end.
A program may have as many data and code segments as required by the
front end.
Each segment may be regarded as an individual file of objects, and may
be created simultaneously.
There is a current segment, selected by BESetSeg(), into which all DG
routines generate their data.
The code for each routine is generated into the segment returned by the
FESegID() call when it is passed the cg_sym_handle for the routine.
It is illegal to write data to the code segment for a routine in
between the CGProcDecl call and the CGReturn call.
:P.The following routines are used for initializing, finalizing,
defining and selecting segments.
.section void BEDefSeg( segment_id id, seg_attr attr, char *str, uint algn )
:I1.BEDefSeg
:I1.segments
:P.Define a segment.
This must be called after BEInit and before BEStart.
For the 80(x)86 code generator, you are allowed to define additional
segments after BEStart if they are:
:OL compact.
:LI.Code Segments
:LI.PRIVATE data segments.
:eOL.
:DL.
:DTHD.Parameter
:DDHD.Definition
:DT.id
:DD.A non-negative integer used as an identifier for the segment.
It is arbitrarily picked by the front end.
:DT.attr
:DD.Segment attribute bits, defined below.
:DT.str
:DD.The name given to the segment.
:DT.algn
:DD.The segment alignment requirements.
The code generator will pick the next larger alignment allowed by the
object module format.
For example, 9 would select paragraph alignment.
:eDL.
:DL.
:DTHD.Attribute
:DDHD.Definition
:DT.EXEC
:DD.This is a code segment.
:DT.GLOBAL
:DD.The segment is accessible to other modules.
(versus PRIVATE).
:DT.INIT
:DD.The segment is statically initialized.
:DT.ROM
:DD.The segment is read only.
:DT.BACK
:DD.The code generator may put its data here.
One segment must be marked with this attribute.
It may not be a COMMON, PRIVATE or EXEC segment.
If the front end requires code in the EXEC segment, the CONST_IN_CODE
switch must be passed to BEInit().
:DT.COMMON
:DD.All occurrences of this segment will be overlayed.
This is used for FORTRAN common blocks.
:DT.PRIVATE
:DD.The segment is non combinable.
This is used for far data items.
:DT.GIVEN_NAME
:DD.Normally, the back end feels free to prepend or append strings to
the segment name passed in by the front end.
This allows a naive front end to specify a constant set of segment
names, and have the code generator mangle them in such a manner that
they work properly in concert with the set of cg_switches that have
been specified (e.g.
prepending the module name to the code segments when BIG_CODE is
specified on the x86).
When GIVEN_NAME is specified, the back end outputs the segment name to
the object file exactly as given.
:DT.NOGROUP
:DD.Segment will not be part of DGROUP (if it is a data segment). Private
segments are never part of DGROUP, but sometimes it is useful to have
segments that are combinable with others but can be physically separate.
:DT.THREAD_LOCAL
:DD.Segment contains thread local data. Such segments may need special
handling in executable modules.
:eDL.
.section segment_id BESetSeg( segment_id seg )
:I1.BESetSeg
:I1.segments
:P.Select the current segment for data generation routines.
Code for a routine is always output into the segment returned by
FESegID when it is passed the routine symbol handle.
:DL.
:DTHD.Parameter
:DDHD.Definition
:DT.seg
:DD.Selects the current segment.
:eDL.
:DL.
:DT.Returns
:DD.The previous current segment.
:eDL.
:NOTE.
When emitting data into an EXEC or BACK segment, be aware that
the code generator is at liberty to emit code and/or back end data into
that segment anytime you make a call to a code generation routine
(CG*).
Do NOT expect data items to be contiguous in the segment if you have
made an intervening CG* call.
.section void BEFlushSeg( segment_id seg )
:I1.BEFlushSeg
:I1.segments
:P.BEFlushSeg informs the back end that no more code/data will be
generated in the specified segment.
For code segments, it must be called after the CGReturn() for the final
function which is placed in the segment.
This causes the code generator to flush all pending information

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?