mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-22 14:19:24 +01:00
+ More information and suggestions
This commit is contained in:
parent
05dae2fe14
commit
94e71486a7
@ -1,15 +1,16 @@
|
|||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
History
|
Module CPUBASE
|
||||||
-------
|
--------------
|
||||||
|
|
||||||
13th oct 1999 remark about alignment added (FK)
|
CONSTANTS used throughout the code generator
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
CVS Log see at the end of that file
|
frame_pointer equals the register used as frame pointer
|
||||||
|
stack_pointer equals the register used as stack pointer
|
||||||
frame_pointer contains the register used as frame pointer
|
self_pointer equals the register used as self pointer
|
||||||
stack_pointer contains the register used as stack pointer
|
accumulator equals the register which will be used
|
||||||
self_pointer contains the register used as self pointer
|
as function return values
|
||||||
|
|
||||||
|
|
||||||
unusedregsint set of Currently available integer registers
|
unusedregsint set of Currently available integer registers
|
||||||
@ -34,6 +35,30 @@ mmregs all!! available multimedia register
|
|||||||
|
|
||||||
lvaluelocations a set of all locations which can be an l-value
|
lvaluelocations a set of all locations which can be an l-value
|
||||||
|
|
||||||
|
Locations
|
||||||
|
---------
|
||||||
|
The first pass assigns these location types which are then
|
||||||
|
used by the code generator to write out the correct instructions:
|
||||||
|
|
||||||
|
LOC_INVALID = This is an error and should never occur
|
||||||
|
LOC_REGISTER = Location is in a register
|
||||||
|
LOC_MEM = Memory reference (symbolic or register address?)
|
||||||
|
LOC_REFERENCE = Memory reference (symbolic or register address?)
|
||||||
|
LOC_JUMP = ????
|
||||||
|
LOC_FLAGS = Value is in the flags (Florian, this will give problems!)
|
||||||
|
LOC_CREGISTER = Value is in a constant register (across calls -
|
||||||
|
used for optimizations) - Constant registers
|
||||||
|
should not be directly modified????
|
||||||
|
LOC_CONST = Value is a numeric constant
|
||||||
|
|
||||||
|
Operand Sizes
|
||||||
|
-------------
|
||||||
|
OS_NO = No operand size.
|
||||||
|
OS_8 = 8-bit signed or unsigned value
|
||||||
|
OS_16 = 16-bit signed or unsigned value
|
||||||
|
OS_32 = 32-bit signed or unsigned value
|
||||||
|
OS_64 = 64-bit signed or unsigned value
|
||||||
|
|
||||||
Intel specific
|
Intel specific
|
||||||
--------------
|
--------------
|
||||||
unusedregssse
|
unusedregssse
|
||||||
@ -78,12 +103,13 @@ The code generation can be seperated into 3 layers:
|
|||||||
3. the code generator object
|
3. the code generator object
|
||||||
|
|
||||||
1.: This procedure does very high level stuff, if the code generation
|
1.: This procedure does very high level stuff, if the code generation
|
||||||
is processor independed, it calls the appropriate procedures of the
|
is processor independent, it calls the appropriate procedures of the
|
||||||
code generator object to generate the code, but in most cases, it
|
code generator object to generate the code, but in most cases, it
|
||||||
calls procedure variables of the second layer
|
calls procedure variables of the second layer
|
||||||
|
|
||||||
2. This procedure variables must be initialized to match to the match the
|
2. This procedure variables must be initialized to match the
|
||||||
current processor
|
current processor, these variables are used to optimize
|
||||||
|
existing processor instructions(? CEC).
|
||||||
|
|
||||||
The following procedure variables are currently used
|
The following procedure variables are currently used
|
||||||
|
|
||||||
@ -94,7 +120,8 @@ p2_assignment_int64_reg Do an assignment of a int64
|
|||||||
|
|
||||||
|
|
||||||
3. The code generator object does very basic operations like generating
|
3. The code generator object does very basic operations like generating
|
||||||
move code etc.
|
move code etc, which is called by the p2_ functions and by the
|
||||||
|
secondpass procedures.
|
||||||
|
|
||||||
Alignment
|
Alignment
|
||||||
---------
|
---------
|
||||||
@ -105,12 +132,196 @@ values: 1,2,4,8,16 (1 means unligned). The code generator must update
|
|||||||
that field at the appropriate places and take care of it when
|
that field at the appropriate places and take care of it when
|
||||||
generating the code
|
generating the code
|
||||||
|
|
||||||
|
MODULE CGOBJ (The code generator object)
|
||||||
|
------------
|
||||||
|
This is the basis of the code generator, it includes several
|
||||||
|
template instructions which are used to create a processor
|
||||||
|
independant code generator.
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
scratch_register_array_pointer : aword;
|
||||||
|
?????????????????????
|
||||||
|
Indicates the free scratch registers?
|
||||||
|
|
||||||
|
unusedscratchregisters : tregisterset;
|
||||||
|
This holds the currently unused registers which can
|
||||||
|
be used as temporary placeholders.
|
||||||
|
|
||||||
|
alignment : talignment; ?? Why is this in cg object, should not
|
||||||
|
this be a constant instead?
|
||||||
|
|
||||||
|
Template instructions
|
||||||
|
---------------------
|
||||||
|
procedure a_call_name
|
||||||
|
|
||||||
|
Call a routine by symbolic name with a possible
|
||||||
|
numeric offset value.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
???? WE ASSUME UNSIGNED???
|
||||||
|
|
||||||
|
{ move instructions }
|
||||||
|
procedure a_load_const_reg
|
||||||
|
--------------------------
|
||||||
|
Move a constant value to a register
|
||||||
|
|
||||||
|
procedure a_load_reg_ref
|
||||||
|
------------------------
|
||||||
|
Move a register value to a memory reference
|
||||||
|
|
||||||
|
procedure a_load_ref_reg
|
||||||
|
------------------------
|
||||||
|
Move the value at a specified address into a register
|
||||||
|
|
||||||
|
procedure a_load_reg_reg
|
||||||
|
------------------------
|
||||||
|
Move from register to register
|
||||||
|
|
||||||
|
WE NEED !!!!MOVE WITH SIGN EXTENSION??????????????????????
|
||||||
|
|
||||||
|
|
||||||
|
{ comparison operations }
|
||||||
|
????????????? WHAT DOES THE LABELS MEAN????????
|
||||||
|
|
||||||
|
procedure a_cmp_reg_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
||||||
|
l : pasmlabel);virtual;
|
||||||
|
procedure a_cmp_reg_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : pasmlabel);
|
||||||
|
procedure a_cmp_reg_ref_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg : tregister;l : pasmlabel);
|
||||||
|
procedure a_cmp_ref_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
||||||
|
l : pasmlabel);
|
||||||
|
|
||||||
|
procedure a_jmp_cond(list : paasmoutput;cond : TOpCmp;l: pasmlabel);
|
||||||
|
|
||||||
|
procedure a_loadaddress_ref_reg(list : paasmoutput;const ref : treference;r : tregister);virtual;
|
||||||
|
|
||||||
|
|
||||||
|
??????????????
|
||||||
|
{ allocates register r by inserting a pai_realloc record }
|
||||||
|
procedure a_reg_alloc(list : paasmoutput;r : tregister);
|
||||||
|
{ deallocates register r by inserting a pa_regdealloc record}
|
||||||
|
procedure a_reg_dealloc(list : paasmoutput;r : tregister);
|
||||||
|
|
||||||
|
|
||||||
|
{ returns a register for use as scratch register }
|
||||||
|
function get_scratch_reg(list : paasmoutput) : tregister;
|
||||||
|
{ releases a scratch register }
|
||||||
|
procedure free_scratch_reg(list : paasmoutput;r : tregister);
|
||||||
|
|
||||||
|
{************************************************}
|
||||||
|
{ code generation for subroutine entry/exit code }
|
||||||
|
|
||||||
|
{ initilizes data of type t }
|
||||||
|
{ if is_already_ref is true then the routines assumes }
|
||||||
|
{ that r points to the data to initialize ???? }
|
||||||
|
procedure g_initialize(list : paasmoutput;t : pdef;const ref : treference;is_already_ref : boolean);
|
||||||
|
|
||||||
|
{ finalizes data of type t }
|
||||||
|
{ if is_already_ref is true then the routines assumes }
|
||||||
|
{ that r points to the data to finalizes ???? }
|
||||||
|
procedure g_finalize(list : paasmoutput;t : pdef;const ref : treference;is_already_ref : boolean);
|
||||||
|
|
||||||
|
{ helper routines }
|
||||||
|
procedure g_initialize_data(list : paasmoutput;p : psym);
|
||||||
|
procedure g_incr_data(list : paasmoutput;p : psym);
|
||||||
|
procedure g_finalize_data(list : paasmoutput;p : pnamedindexobject);
|
||||||
|
procedure g_copyvalueparas(list : paasmoutput;p : pnamedindexobject);
|
||||||
|
procedure g_finalizetempansistrings(list : paasmoutput);
|
||||||
|
|
||||||
|
procedure g_entrycode(list : paasmoutput;
|
||||||
|
const proc_names : tstringcontainer;make_global : boolean;
|
||||||
|
stackframe : longint;var parasize : longint;
|
||||||
|
var nostackframe : boolean;inlined : boolean);
|
||||||
|
|
||||||
|
procedure g_exitcode(list : paasmoutput;parasize : longint;
|
||||||
|
nostackframe,inlined : boolean);
|
||||||
|
|
||||||
|
{ string helper routines }
|
||||||
|
procedure g_decrstrref(list : paasmoutput;const ref : treference;t : pdef);
|
||||||
|
|
||||||
|
procedure g_removetemps(list : paasmoutput;p : plinkedlist);
|
||||||
|
|
||||||
|
{ passing parameters, per default the parameter is pushed }
|
||||||
|
{ nr gives the number of the parameter (enumerated from }
|
||||||
|
{ left to right), this allows to move the parameter to }
|
||||||
|
{ register, if the cpu supports register calling }
|
||||||
|
{ conventions }
|
||||||
|
procedure a_param_reg(list : paasmoutput;size : tcgsize;r : tregister;nr : longint);virtual;
|
||||||
|
procedure a_param_const(list : paasmoutput;size : tcgsize;a : aword;nr : longint);virtual;
|
||||||
|
procedure a_param_ref(list : paasmoutput;size : tcgsize;const r : treference;nr : longint);virtual;
|
||||||
|
procedure a_paramaddr_ref(list : paasmoutput;const r : treference;nr : longint);virtual;
|
||||||
|
|
||||||
|
{**********************************}
|
||||||
|
{ these methods must be overriden: }
|
||||||
|
|
||||||
|
{ Remarks:
|
||||||
|
* If a method specifies a size you have only to take care
|
||||||
|
of that number of bits, i.e. load_const_reg with OP_8 must
|
||||||
|
only load the lower 8 bit of the specified register
|
||||||
|
the rest of the register can be undefined
|
||||||
|
if necessary the compiler will call a method
|
||||||
|
to zero or sign extend the register
|
||||||
|
* The a_load_XX_XX with OP_64 needn't to be
|
||||||
|
implemented for 32 bit
|
||||||
|
processors, the code generator takes care of that
|
||||||
|
* the addr size is for work with the natural pointer
|
||||||
|
size
|
||||||
|
* the procedures without fpu/mm are only for integer usage
|
||||||
|
* normally the first location is the source and the
|
||||||
|
second the destination
|
||||||
|
}
|
||||||
|
Virtual instruction templates:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure g_stackframe_entry(list : paasmoutput;localsize : longint);virtual;
|
||||||
|
{ restores the frame pointer at procedure exit, for the }
|
||||||
|
{ i386 it generates a simple leave }
|
||||||
|
procedure g_restore_frame_pointer(list : paasmoutput);virtual;
|
||||||
|
|
||||||
|
{ some processors like the PPC doesn't allow to change the stack in }
|
||||||
|
{ a procedure, so we need to maintain an extra stack for the }
|
||||||
|
{ result values of setjmp in exception code }
|
||||||
|
{ this two procedures are for pushing an exception value, }
|
||||||
|
{ they can use the scratch registers }
|
||||||
|
procedure g_push_exception_value_reg(list : paasmoutput;reg : tregister);virtual;
|
||||||
|
procedure g_push_exception_value_const(list : paasmoutput;reg : tregister);virtual;
|
||||||
|
{ that procedure pops a exception value }
|
||||||
|
procedure g_pop_exception_value_reg(list : paasmoutput;reg : tregister);virtual;
|
||||||
|
procedure g_return_from_proc(list : paasmoutput;parasize : aword);virtual;
|
||||||
|
{********************************************************}
|
||||||
|
{ these methods can be overriden for extra functionality }
|
||||||
|
|
||||||
|
{ the following methods do nothing: }
|
||||||
|
procedure g_interrupt_stackframe_entry(list : paasmoutput);virtual;
|
||||||
|
procedure g_interrupt_stackframe_exit(list : paasmoutput);virtual;
|
||||||
|
|
||||||
|
procedure g_profilecode(list : paasmoutput);virtual;
|
||||||
|
procedure g_stackcheck(list : paasmoutput;stackframesize : longint);virtual;
|
||||||
|
|
||||||
|
procedure a_load_const_ref(list : paasmoutput;size : tcgsize;a : aword;const ref : treference);virtual;
|
||||||
|
procedure g_maybe_loadself(list : paasmoutput);virtual;
|
||||||
|
{ copies len bytes from the source to destination, if }
|
||||||
|
{ loadref is true, it assumes that it first must load }
|
||||||
|
{ the source address from the memory location where }
|
||||||
|
{ source points to }
|
||||||
|
procedure g_concatcopy(list : paasmoutput;const source,dest : treference;len : aword;loadref : boolean);virtual;
|
||||||
|
|
||||||
|
{ uses the addr of ref as param, was emitpushreferenceaddr }
|
||||||
|
procedure a_param_ref_addr(list : paasmoutput;r : treference;nr : longint);virtual;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CVS Log
|
CVS Log
|
||||||
-------
|
-------
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.5 2000-03-01 15:36:12 florian
|
Revision 1.6 2000-03-02 03:22:16 carl
|
||||||
|
+ More information and suggestions
|
||||||
|
|
||||||
|
Revision 1.5 2000/03/01 15:36:12 florian
|
||||||
* some new stuff for the new cg
|
* some new stuff for the new cg
|
||||||
|
|
||||||
Revision 1.4 1999/10/14 14:57:54 florian
|
Revision 1.4 1999/10/14 14:57:54 florian
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user