123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- $Id$
- Module CPUBASE
- --------------
- CONSTANTS used throughout the code generator
- --------------------------------------------
- Must of this is subject to be moved to cpuinfo
- frame_pointer equals the register used as frame pointer
- stack_pointer equals the register used as stack pointer
- self_pointer equals the register used as self pointer
- accumulator equals the register which will be used
- as function return values
- unusedregsint set of Currently available integer registers
- unusedregsfpu set of Currently available fpu registers
- unusedregsmm set of Currently available mm registers
- availabletempregsint set of maximally available integer registers
- availabletempregsfpu set of maximally available fpu registers
- availabletempregsmm set of maximally available mm registers
- countusableregsint count of currently available integer registers
- countusableregsfpu count of currently available fpu registers
- countusableregsmm count of currently available mm registers
- c_countusableregsint count of max. available int registers (in the current procedure)
- c_countusableregsfpu count of max. available fpu registers (in the current procedure)
- c_countusableregsmm count of max. available mm registers (in the current procedure)
- intregs all!! available integer register
- fpuregs all!! available fpu register
- mmregs all!! available multimedia register
- 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
- --------------
- unusedregssse
- availabletempregssse
- countusableregssse
- Jonas Maebe schrieb:
- >
- > Hello,
- >
- > Is there any difference between the localsize parameter of
- > g_stackframe_entry and the parasize parameter of g_return_from_proc, or
- > are they both the same value?
- They are different, I think the value of g_return_from_proc doesn't matter
- for the PowerPC. It's the size of parameters passed on the stack
- and only important for the i386/m68k probably.
- >
- > And for the PowerPC, what will they contain? Just the size of the local
- > variables and parameters, or also the maximum needed size for parameters
- > of any procedure called by the current one (the caller must reserve space
- > for the callee's parameters on it's own stack because you can't push
- > values on the stack in the middle of a procedure (no frame pointer))
- >
- > Jonas
- the parameter passed to g_stackframe_entry contains the size of the all local space which is
- needed
- except
- that one for saving registers: the set procinfo.registerstosave (not yet implemented,
- I'll commit it soon) will contain
- all registers which must be saved by the entry and restored by the exit code of a procedure
- and you have to add extra space to do that.
- The code generation
- -------------------
- The code generation can be seperated into 3 layers:
- 1. the method secondpass of the tnode childs
- 2. the procedure variables p2_
- 3. the code generator object
- 1.: This procedure does very high level stuff, if the code generation
- is processor independent, it calls the appropriate procedures of the
- code generator object to generate the code, but in most cases, it
- calls procedure variables of the second layer
- 2. This procedure variables must be initialized to match the
- current processor, these variables are used to optimize
- existing processor instructions(? CEC).
- The following procedure variables are currently used
- Name Purpose Alternatives
- -----------------------------------------------------------------------------
- p2_assignment
- p2_assignment_int64_reg Do an assignment of a int64
- 3. The code generator object does very basic operations like generating
- move code etc, which is called by the p2_ functions and by the
- secondpass procedures.
- Alignment
- ---------
- The alignment is handled very easily: treference contains a field
- alignment which describes the ensured alignment for the node, possible
- 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
- 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
- -------
- $Log$
- Revision 1.3 2002-09-07 15:25:14 peter
- * old logs removed and tabs fixed
|