Browse Source

* moved to main compiler dir

Jonas Maebe 24 years ago
parent
commit
eea498a0ed
2 changed files with 0 additions and 2686 deletions
  1. 0 1290
      compiler/new/cgflw.pas
  2. 0 1396
      compiler/new/cgobj.pas

+ 0 - 1290
compiler/new/cgflw.pas

@@ -1,1290 +0,0 @@
-{
-    $Id$
-    Copyright (c) 1998-2000 by Florian Klaempfl
-
-    Generate ppc assembler for nodes that influence the flow
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit ncpuflw;
-
-{$i defines.inc}
-
-interface
-
-    uses
-      node,nflw;
-
-    type
-       tcpuwhilerepeatnode = class(twhilerepeatnode)
-          procedure pass_2;override;
-       end;
-
-       tcpuifnode = class(tifnode)
-          procedure pass_2;override;
-       end;
-
-       tcpufornode = class(tfornode)
-          procedure pass_2;override;
-       end;
-
-       tcpuexitnode = class(texitnode)
-          procedure pass_2;override;
-       end;
-
-       tcpubreaknode = class(tbreaknode)
-          procedure pass_2;override;
-       end;
-
-       tcpucontinuenode = class(tcontinuenode)
-          procedure pass_2;override;
-       end;
-
-       tcpugotonode = class(tgotonode)
-          procedure pass_2;override;
-       end;
-
-       tcpulabelnode = class(tlabelnode)
-          procedure pass_2;override;
-       end;
-
-       tcpuraisenode = class(traisenode)
-          procedure pass_2;override;
-       end;
-
-       tcputryexceptnode = class(ttryexceptnode)
-          procedure pass_2;override;
-       end;
-
-       tcputryfinallynode = class(ttryfinallynode)
-          procedure pass_2;override;
-       end;
-
-       tcpuonnode = class(tonnode)
-          procedure pass_2;override;
-       end;
-
-       tcpufailnode = class(tfailnode)
-          procedure pass_2;override;
-       end;
-
-implementation
-
-    uses
-      verbose,globtype,globals,systems,
-      symconst,symdef,symsym,aasm,types,
-      cgbase,temp_gen,pass_2,
-      cpubase,cpuasm,
-      pass_1,nld,ncon,
-      cga,tgcpu,n386util,regvars;
-
-{*****************************************************************************
-                         Second_While_RepeatN
-*****************************************************************************}
-
-    procedure tcpuwhilerepeatnode.pass_2;
-      var
-         lcont,lbreak,lloop,
-         oldclabel,oldblabel : tasmlabel;
-         otlabel,oflabel : tasmlabel;
-
-      begin
-         getlabel(lloop);
-         getlabel(lcont);
-         getlabel(lbreak);
-         { arrange continue and breaklabels: }
-         oldclabel:=aktcontinuelabel;
-         oldblabel:=aktbreaklabel;
-
-         load_all_regvars(exprasmlist);
-         { handling code at the end as it is much more efficient, and makes
-           while equal to repeat loop, only the end true/false is swapped (PFV) }
-         if nodetype=whilen then
-           cgcpu.a_jmp_cond(exprasmlist,OC_None,lcont);
-
-         { align loop target }
-         exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
-         cgcpu.cgcpu.a_label(exprasmlist,lloop);
-
-         aktcontinuelabel:=lcont;
-         aktbreaklabel:=lbreak;
-         cleartempgen;
-         if assigned(right) then
-           secondpass(right);
-
-         load_all_regvars(exprasmlist);
-
-         cgcpu.a_label(exprasmlist,lcont);
-         otlabel:=truelabel;
-         oflabel:=falselabel;
-         if nodetype=whilen then
-          begin
-            truelabel:=lloop;
-            falselabel:=lbreak;
-          end
-         { repeatn }
-         else
-          begin
-            truelabel:=lbreak;
-            falselabel:=lloop;
-          end;
-         cleartempgen;
-         secondpass(left);
-
-         load_all_regvars(exprasmlist);
-
-         maketojumpbool(left);
-         cgcpu.a_label(exprasmlist,lbreak);
-         truelabel:=otlabel;
-         falselabel:=oflabel;
-
-
-         aktcontinuelabel:=oldclabel;
-         aktbreaklabel:=oldblabel;
-         { a break/continue in a while/repeat block can't be seen outside }
-         flowcontrol:=flowcontrol-[fc_break,fc_continue];
-      end;
-
-
-{*****************************************************************************
-                               TCPUIFNODE
-*****************************************************************************}
-
-    procedure tcpuifnode.pass_2;
-
-      var
-         hl,otlabel,oflabel : tasmlabel;
-
-      begin
-         otlabel:=truelabel;
-         oflabel:=falselabel;
-         getlabel(truelabel);
-         getlabel(falselabel);
-         cleartempgen;
-         secondpass(left);
-         load_all_regvars(exprasmlist);
-         maketojumpbool(left);
-         if assigned(right) then
-           begin
-              cgcpu.a_label(truelabel);
-              cleartempgen;
-              secondpass(right);
-              { automatically done for blocks, but not for statements (JM) }
-              load_all_regvars(exprasmlist);
-           end;
-         if assigned(t1) then
-           begin
-              if assigned(right) then
-                begin
-                   getlabel(hl);
-                   { do go back to if line !! }
-                   aktfilepos:=exprasmList.getlasttaifilepos^;
-                   cgcpu.a_jmp_cond(exprasmlist,OC_None,hl);
-                end;
-              cgcpu.a_label(exprasmlist,falselabel);
-              cleartempgen;
-              secondpass(t1);
-              load_all_regvars(exprasmlist);
-              if assigned(right) then
-                cgcpu.a_label(exprasmlist,hl);
-           end
-         else
-           begin
-              cgcpu.a_label(exprasmlist,falselabel);
-           end;
-         if not(assigned(right)) then
-           begin
-              cgcpu.a_label(exprasmlist,truelabel);
-           end;
-         truelabel:=otlabel;
-         falselabel:=oflabel;
-      end;
-
-
-{*****************************************************************************
-                              SecondFor
-*****************************************************************************}
-
-    procedure tcpufornode.pass_2;
-      var
-         l3,oldclabel,oldblabel : tasmlabel;
-         omitfirstcomp,temptovalue : boolean;
-         hs : byte;
-         temp1 : treference;
-         hop : tasmop;
-         hcond : topcg;
-         opsize : tcgsize;
-         count_var_is_signed : boolean;
-
-      begin
-         oldclabel:=aktcontinuelabel;
-         oldblabel:=aktbreaklabel;
-         getlabel(aktcontinuelabel);
-         getlabel(aktbreaklabel);
-         getlabel(l3);
-
-         { could we spare the first comparison ? }
-         omitfirstcomp:=false;
-         if right.nodetype=ordconstn then
-           if tassignmentnode(left).right.nodetype=ordconstn then
-             omitfirstcomp:=((nf_backward in flags) and
-               (tordconstnode(tassignmentnode(left).right).value>=tordconstnode(right).value))
-               or (not(nf_backward in flags) and
-                  (tordconstnode(tassignmentnode(left).right).value<=tordconstnode(right).value));
-
-         { only calculate reference }
-         cleartempgen;
-         secondpass(t2);
-         hs := t2.resulttype.def.size;
-         opsize := def_opsize(t2.resulttype.def);
-
-         { first set the to value
-           because the count var can be in the expression !! }
-         cleartempgen;
-         secondpass(right);
-         { calculate pointer value and check if changeable and if so }
-         { load into temporary variable                       }
-         if right.nodetype<>ordconstn then
-           begin
-              temp1.symbol:=nil;
-              gettempofsizereference(hs,temp1);
-              temptovalue:=true;
-              if (right.location.loc=LOC_REGISTER) or
-                 (right.location.loc=LOC_CREGISTER) then
-                begin
-                   cgcpu.a_load_reg_ref(exprasmlist,opsize,
-                     right.location.register,temp1);
-                 end
-              else
-                 cgcpu.g_concatcopy(exprasmlist,right.location.reference,temp1,
-                   hs,false,false);
-           end
-         else
-           temptovalue:=false;
-
-         { produce start assignment }
-         cleartempgen;
-         secondpass(left);
-         count_var_is_signed:=is_signed(torddef(t2.resulttype.def));
-
-         if nf_backward in flags then
-           if count_var_is_signed then
-             hcond:=OC_LT
-           else
-             hcond:=OC_B
-         else
-           if count_var_is_signed then
-             hcond:=OC_GT
-           else
-             hcond:=OC_A;
-
-         load_all_regvars(exprasmlist);
-
-         if temptovalue then
-           begin
-             cgcpu.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
-               temp1,t2.location,aktbreaklabel);
-           end
-         else
-           begin
-             if not(omitfirstcomp) then
-               begin
-                 cgcpu.a_cmp_const_loc(exprasmlist,opsize,hcond,
-                   tordconstnode(right).value,t2.location,aktbreaklabel);
-               end;
-           end;
-
-         { align loop target }
-         exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
-         cgcpu.a_label(exprasmlist,l3);
-
-         { help register must not be in instruction block }
-         cleartempgen;
-         if assigned(t1) then
-           begin
-             secondpass(t1);
-             load_all_regvars(exprasmlist);
-           end;
-
-         cgcpu.a_label(exprasmlist,aktcontinuelabel);
-
-         { makes no problems there }
-         cleartempgen;
-
-         if nf_backward in flags then
-           if count_var_is_signed then
-             hcond:=OC_LE
-           else
-             hcond:=OC_BE
-          else
-            if count_var_is_signed then
-              hcond:=OC_GE
-            else
-              hcond:=OC_AE;
-         load_all_regvars(exprasmlist);
-
-         { produce comparison and the corresponding }
-         { jump                              }
-         if temptovalue then
-           begin
-             cgcpu.a_cmp_ref_loc(exprasmlist,opsize,hcond,temp1,
-               t2.location,aktbreaklabel);
-           end
-         else
-           begin
-             cgcpu.a_cmp_const_loc_label(exprasmlist,opsize,hcond,tordconstnode(right).value,
-               t2.location,aktbreaklabel);
-           end;
-         e(hcond,aktbreaklabel);
-         { according to count direction DEC or INC... }
-         { must be after the test because of 0 to 255 for bytes !! }
-         if nf_backward in flags then
-           hop:=OP_ADD
-         else
-           hop:=OP_SUB;
-
-         a_op_loc_const(exprasmlist,hop,opsize,t2.location,1);
-         a_jmp_cond(exprasmlist,OC_None,l3);
-
-         if temptovalue then
-           ungetiftemp(temp1);
-
-         { this is the break label: }
-         cgcpu.a_label(exptrasmlist,aktbreaklabel);
-
-         aktcontinuelabel:=oldclabel;
-         aktbreaklabel:=oldblabel;
-         { a break/continue in a for block can't be seen outside }
-         flowcontrol:=flowcontrol-[fc_break,fc_continue];
-      end;
-
-
-{*****************************************************************************
-                              SecondExitN
-*****************************************************************************}
-
-    procedure ti386exitnode.pass_2;
-
-      var
-         {op : tasmop;
-         s : topsize;}
-         otlabel,oflabel : tasmlabel;
-         r : treference;
-         is_mem,
-         allocated_acc,
-         allocated_acchigh: boolean;
-
-      procedure cleanleft;
-        begin
-          if is_mem then
-            begin
-              del_reference(left.location.reference);
-              ungetiftemp(left.location.reference);
-            end
-          else
-            begin
-              ungetregister(left.location.register);
-              if left.location.registerhigh <> R_NO then
-                ungetregister(left.location.registerhigh);
-            end;
-        end;
-
-      label
-         do_jmp;
-      begin
-         load_all_regvars(exprasmlist);
-         include(flowcontrol,fc_exit);
-         if assigned(left) then
-         if left.nodetype=assignn then
-           begin
-              { just do a normal assignment followed by exit }
-              secondpass(left);
-              cgcpu.a_jmp_cond(exprasmlist,C_None,aktexitlabel);
-           end
-         else
-           begin
-              allocated_acc := false;
-              allocated_acchigh := false;
-              otlabel:=truelabel;
-              oflabel:=falselabel;
-              getlabel(truelabel);
-              getlabel(falselabel);
-              secondpass(left);
-              case left.location.loc of
-                 LOC_FPU : goto do_jmp;
-                 LOC_MEM,
-           LOC_REFERENCE : is_mem:=true;
-           LOC_CREGISTER,
-            LOC_REGISTER : is_mem:=false;
-               LOC_FLAGS : begin
-                             cgcpu.a_reg_alloc(exprasmlist,accumulator);
-                             allocated_acc := true;
-                             cgcpu.g_flag2reg(left.location.resflags,accumulator);
-                             goto do_jmp;
-                           end;
-                LOC_JUMP : begin
-                             exprasmlist.concat(tairegalloc.alloc(accumulator));
-                             allocated_acc := true;
-                             cgcpu.a_label(exprasmlist,truelabel);
-                             cgcpu.a_load_const_reg(exprasmlist,OS_8,1,acc);
-                             cgcpu.a_jmp_cond(exprasmlist,C_None,aktexit2label);
-                             cgcpu.a_label(exprasmlist,falselabel);
-                             cgcpu.a_load_const_reg(exprasmlist,OS_8,0,acc);
-                             goto do_jmp;
-                           end;
-              else
-                internalerror(2001);
-              end;
-              case aktprocsym.definition.rettype.def.deftype of
-           pointerdef,
-           procvardef : begin
-                          cleanleft;
-                          cgcpu.a_reg_alloc(exprasmlist,accumulator);
-                          allocated_acc := true;
-                          if is_mem then
-                            cgcpu.a_load_ref_reg(exprasmlist,OS_ADDR,
-                              left.location.reference,accumulator)
-                          else
-                            cgcpu.a_load_reg_reg(exprasmlist,OS_ADDR,
-                              left.location.register,accumulator);
-                        end;
-             floatdef : begin
-                          cleanleft;
-                          if is_mem then
-                           floatload(tfloatdef(aktprocsym.definition.rettype.def).typ,left.location.reference);
-                        end;
-              { orddef,
-              enumdef : }
-              else
-              { it can be anything shorter than 4 bytes PM
-              this caused form bug 711 }
-                begin
-                   cleanleft;
-                   cgcpu.a_reg_alloc(exprasmlist,accumulator);
-                   allocated_acc := true;
-                   case aktprocsym.definition.rettype.def.size of
-                    { it can be a qword/int64 too ... }
-                    8 :
-                      if is_mem then
-                        begin
-                           cgcpu.load_ref_reg(exprasmlist,OS_32,
-                             left.location.reference,accumulator);
-                           r:=left.location.reference;
-                           inc(r.offset,4);
-                           cgcpu.a_reg_alloc(exprasmlist,accumulatorhigh);
-                           allocated_acchigh := true;
-                           cgcpu.load_ref_reg(exprasmlist,OS_32,r,accumulatorhigh);
-                        end
-                      else
-                        begin
-                           cgcpu.load_reg_reg(exprasmlist,OS_32,left.location.registerlow,accumulator);
-                           cgcpu.a_reg_alloc(exprasmlist,accumulatorhigh);
-                           allocated_acchigh := true;
-                           cgcpu.load_reg_reg(exprasmlist,OS_32,left.location.registerhigh,accumulatorhigh);
-                        end;
-                   { if its 3 bytes only we can still
-                     copy one of garbage ! PM }
-                    4,3 :
-                      cgcpu.load_loc_reg(exprasmlist,OS_32,left.location.reference,
-                        accumulator);
-                    2 :
-                      cgcpu.load_loc_reg(exprasmlist,OS_16,left.location.reference,
-                        makereg16(accumulator));
-                    1 :
-                      cgcpu.load_loc_reg(exprasmlist,OS_8,left.location.reference,
-                        makereg8(accumulator));
-                    else internalerror(605001);
-                   end;
-                 end;
-              end;
-do_jmp:
-              truelabel:=otlabel;
-              falselabel:=oflabel;
-              cgcpu.a_jmp_cond(exprasmlist,OC_None,aktexit2label);
-              if allocated_acc then
-                cgcpu.a_reg_dealloc(exprasmlist,accumulator);
-              if allocated_acchigh then
-                cgcpu.a_reg_dealloc(exprasmlist,accumulator);
-           end
-         else
-            cgcpu.a_jmp_cond(exprasmlist,OC_None,aktexitlabel);
-       end;
-
-
-{*****************************************************************************
-                              SecondBreakN
-*****************************************************************************}
-
-    procedure ti386breaknode.pass_2;
-      begin
-         include(flowcontrol,fc_break);
-         if aktbreaklabel<>nil then
-           begin
-             load_all_regvars(exprasmlist);
-             cgcpu.a_jmp_cond(expraslist,OC_None,aktbreaklabel)
-           end
-         else
-           CGMessage(cg_e_break_not_allowed);
-      end;
-
-
-{*****************************************************************************
-                              SecondContinueN
-*****************************************************************************}
-
-    procedure ti386continuenode.pass_2;
-      begin
-         include(flowcontrol,fc_continue);
-         if aktcontinuelabel<>nil then
-           begin
-             load_all_regvars(exprasmlist);
-             cgcpu.a_jmp_cond(expraslist,OC_None,aktcontinuelabel)
-           end
-         else
-           CGMessage(cg_e_continue_not_allowed);
-      end;
-
-
-{*****************************************************************************
-                             SecondGoto
-*****************************************************************************}
-
-    procedure ti386gotonode.pass_2;
-
-       begin
-         load_all_regvars(exprasmlist);
-         cgcpu.a_jmp_cond(expraslist,OC_None,labelnr)
-       end;
-
-
-{*****************************************************************************
-                             SecondLabel
-*****************************************************************************}
-
-    procedure ti386labelnode.pass_2;
-      begin
-         load_all_regvars(exprasmlist);
-         cgcpu.a_label(exprasmlist,labelnr);
-         cleartempgen;
-         secondpass(left);
-      end;
-
-
-{*****************************************************************************
-                             SecondRaise
-*****************************************************************************}
-
-    procedure ti386raisenode.pass_2;
-
-      var
-         a : tasmlabel;
-      begin
-         if assigned(left) then
-           begin
-              { multiple parameters? }
-              if assigned(right) then
-                begin
-                  { push frame }
-                  if assigned(frametree) then
-                    begin
-                      secondpass(frametree);
-                      if codegenerror then
-                       exit;
-                      emit_push_loc(frametree.location);
-                    end
-                  else
-                    emit_const(A_PUSH,S_L,0);
-                  { push address }
-                  secondpass(right);
-                  if codegenerror then
-                   exit;
-                  emit_push_loc(right.location);
-                end
-              else
-                begin
-                   getaddrlabel(a);
-                   emitlab(a);
-                   emit_reg(A_PUSH,S_L,R_EBP);
-                   emit_sym(A_PUSH,S_L,a);
-                end;
-              { push object }
-              secondpass(left);
-              if codegenerror then
-                exit;
-              emit_push_loc(left.location);
-              emitcall('FPC_RAISEEXCEPTION');
-           end
-         else
-           begin
-              emitcall('FPC_POPADDRSTACK');
-              emitcall('FPC_RERAISE');
-           end;
-       end;
-
-
-{*****************************************************************************
-                             SecondTryExcept
-*****************************************************************************}
-
-    var
-       endexceptlabel : tasmlabel;
-
-    { does the necessary things to clean up the object stack }
-    { in the except block                                    }
-    procedure cleanupobjectstack;
-
-      begin
-         emitcall('FPC_POPOBJECTSTACK');
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_DESTROYEXCEPTION');
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         maybe_loadself;
-      end;
-
-    { pops one element from the exception address stack }
-    { and removes the flag                              }
-    procedure cleanupaddrstack;
-
-      begin
-         emitcall('FPC_POPADDRSTACK');
-         { allocate eax }
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_POP,S_L,R_EAX);
-         { deallocate eax }
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-      end;
-
-    procedure ti386tryexceptnode.pass_2;
-
-      var
-         exceptlabel,doexceptlabel,oldendexceptlabel,
-         lastonlabel,
-         exitexceptlabel,
-         continueexceptlabel,
-         breakexceptlabel,
-         exittrylabel,
-         continuetrylabel,
-         breaktrylabel,
-         doobjectdestroy,
-         doobjectdestroyandreraise,
-         oldaktexitlabel,
-         oldaktexit2label,
-         oldaktcontinuelabel,
-         oldaktbreaklabel : tasmlabel;
-         oldflowcontrol,tryflowcontrol,
-         exceptflowcontrol : tflowcontrol;
-         tempbuf,tempaddr : treference;
-
-      label
-         errorexit;
-      begin
-         oldflowcontrol:=flowcontrol;
-         flowcontrol:=[];
-         { this can be called recursivly }
-         oldendexceptlabel:=endexceptlabel;
-
-         { we modify EAX }
-         usedinproc:=usedinproc or ($80 shr byte(R_EAX));
-
-         { save the old labels for control flow statements }
-         oldaktexitlabel:=aktexitlabel;
-         oldaktexit2label:=aktexit2label;
-         if assigned(aktbreaklabel) then
-           begin
-              oldaktcontinuelabel:=aktcontinuelabel;
-              oldaktbreaklabel:=aktbreaklabel;
-           end;
-
-         { get new labels for the control flow statements }
-         getlabel(exittrylabel);
-         getlabel(exitexceptlabel);
-         if assigned(aktbreaklabel) then
-           begin
-              getlabel(breaktrylabel);
-              getlabel(continuetrylabel);
-              getlabel(breakexceptlabel);
-              getlabel(continueexceptlabel);
-           end;
-
-         getlabel(exceptlabel);
-         getlabel(doexceptlabel);
-         getlabel(endexceptlabel);
-         getlabel(lastonlabel);
-
-         gettempofsizereferencepersistant(24,tempbuf);
-         gettempofsizereferencepersistant(12,tempaddr);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         push_int (1); { push type of exceptionframe }
-         emitcall('FPC_PUSHEXCEPTADDR');
-
-         { allocate eax }
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_SETJMP');
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
-         { deallocate eax }
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitjmp(C_NE,exceptlabel);
-
-         { try block }
-         { set control flow labels for the try block }
-         aktexitlabel:=exittrylabel;
-         aktexit2label:=exittrylabel;
-         if assigned(oldaktbreaklabel) then
-          begin
-            aktcontinuelabel:=continuetrylabel;
-            aktbreaklabel:=breaktrylabel;
-          end;
-
-         flowcontrol:=[];
-         secondpass(left);
-         tryflowcontrol:=flowcontrol;
-         if codegenerror then
-           goto errorexit;
-
-         emitlab(exceptlabel);
-         emitcall('FPC_POPADDRSTACK');
-         ungetpersistanttempreference(tempaddr);
-         ungetpersistanttempreference(tempbuf);
-
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_POP,S_L,R_EAX);
-         emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-
-         emitjmp(C_E,endexceptlabel);
-         emitlab(doexceptlabel);
-
-         { set control flow labels for the except block }
-         { and the on statements                        }
-         aktexitlabel:=exitexceptlabel;
-         aktexit2label:=exitexceptlabel;
-         if assigned(oldaktbreaklabel) then
-          begin
-            aktcontinuelabel:=continueexceptlabel;
-            aktbreaklabel:=breakexceptlabel;
-          end;
-
-         flowcontrol:=[];
-         { on statements }
-         if assigned(right) then
-           secondpass(right);
-
-         emitlab(lastonlabel);
-         { default handling except handling }
-         if assigned(t1) then
-           begin
-              { FPC_CATCHES must be called with
-                'default handler' flag (=-1)
-              }
-              push_int (-1);
-              emitcall('FPC_CATCHES');
-              maybe_loadself;
-
-              { the destruction of the exception object must be also }
-              { guarded by an exception frame                        }
-              getlabel(doobjectdestroy);
-              getlabel(doobjectdestroyandreraise);
-
-              gettempofsizereferencepersistant(12,tempaddr);
-              gettempofsizereferencepersistant(24,tempbuf);
-              emitpushreferenceaddr(tempaddr);
-              emitpushreferenceaddr(tempbuf);
-              exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
-              emitcall('FPC_PUSHEXCEPTADDR');
-
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              emitcall('FPC_SETJMP');
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-              exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              emitjmp(C_NE,doobjectdestroyandreraise);
-
-              { here we don't have to reset flowcontrol           }
-              { the default and on flowcontrols are handled equal }
-              secondpass(t1);
-              exceptflowcontrol:=flowcontrol;
-
-              emitlab(doobjectdestroyandreraise);
-              emitcall('FPC_POPADDRSTACK');
-              ungetpersistanttempreference(tempaddr);
-              ungetpersistanttempreference(tempbuf);
-
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_EAX));
-              exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              emitjmp(C_E,doobjectdestroy);
-              emitcall('FPC_POPSECONDOBJECTSTACK');
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emit_reg(A_PUSH,S_L,R_EAX);
-              emitcall('FPC_DESTROYEXCEPTION');
-              exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-              { we don't need to restore esi here because reraise never }
-              { returns                                                 }
-              emitcall('FPC_RERAISE');
-
-              emitlab(doobjectdestroy);
-              cleanupobjectstack;
-              emitjmp(C_None,endexceptlabel);
-           end
-         else
-           begin
-              emitcall('FPC_RERAISE');
-              exceptflowcontrol:=flowcontrol;
-           end;
-
-         if fc_exit in exceptflowcontrol then
-           begin
-              { do some magic for exit in the try block }
-              emitlab(exitexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cleanupaddrstack;
-              cleanupobjectstack;
-              emitjmp(C_None,oldaktexitlabel);
-           end;
-
-         if fc_break in exceptflowcontrol then
-           begin
-              emitlab(breakexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cleanupaddrstack;
-              cleanupobjectstack;
-              emitjmp(C_None,oldaktbreaklabel);
-           end;
-
-         if fc_continue in exceptflowcontrol then
-           begin
-              emitlab(continueexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cleanupaddrstack;
-              cleanupobjectstack;
-              emitjmp(C_None,oldaktcontinuelabel);
-           end;
-
-         if fc_exit in tryflowcontrol then
-           begin
-              { do some magic for exit in the try block }
-              emitlab(exittrylabel);
-              cleanupaddrstack;
-              emitjmp(C_None,oldaktexitlabel);
-           end;
-
-         if fc_break in tryflowcontrol then
-           begin
-              emitlab(breaktrylabel);
-              cleanupaddrstack;
-              emitjmp(C_None,oldaktbreaklabel);
-           end;
-
-         if fc_continue in tryflowcontrol then
-           begin
-              emitlab(continuetrylabel);
-              cleanupaddrstack;
-              emitjmp(C_None,oldaktcontinuelabel);
-           end;
-
-         emitlab(endexceptlabel);
-
-       errorexit:
-         { restore all saved labels }
-         endexceptlabel:=oldendexceptlabel;
-
-         { restore the control flow labels }
-         aktexitlabel:=oldaktexitlabel;
-         aktexit2label:=oldaktexit2label;
-         if assigned(oldaktbreaklabel) then
-          begin
-            aktcontinuelabel:=oldaktcontinuelabel;
-            aktbreaklabel:=oldaktbreaklabel;
-          end;
-
-         { return all used control flow statements }
-         flowcontrol:=oldflowcontrol+exceptflowcontrol+
-           tryflowcontrol;
-      end;
-
-    procedure ti386onnode.pass_2;
-      var
-         nextonlabel,
-         exitonlabel,
-         continueonlabel,
-         breakonlabel,
-         oldaktexitlabel,
-         oldaktexit2label,
-         oldaktcontinuelabel,
-         doobjectdestroyandreraise,
-         doobjectdestroy,
-         oldaktbreaklabel : tasmlabel;
-         ref : treference;
-         oldflowcontrol : tflowcontrol;
-         tempbuf,tempaddr : treference;
-
-      begin
-         oldflowcontrol:=flowcontrol;
-         flowcontrol:=[];
-         getlabel(nextonlabel);
-
-         { push the vmt }
-         emit_sym(A_PUSH,S_L,
-           newasmsymbol(excepttype.vmt_mangledname));
-         emitcall('FPC_CATCHES');
-         { allocate eax }
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
-         emitjmp(C_E,nextonlabel);
-         ref.symbol:=nil;
-         gettempofsizereference(4,ref);
-
-         { what a hack ! }
-         if assigned(exceptsymtable) then
-           tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
-
-         emit_reg_ref(A_MOV,S_L,
-           R_EAX,newreference(ref));
-         { deallocate eax }
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-
-         { in the case that another exception is risen }
-         { we've to destroy the old one                }
-         getlabel(doobjectdestroyandreraise);
-
-         gettempofsizereferencepersistant(12,tempaddr);
-         gettempofsizereferencepersistant(24,tempbuf);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
-         emitcall('FPC_PUSHEXCEPTADDR');
-
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitcall('FPC_SETJMP');
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
-         exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitjmp(C_NE,doobjectdestroyandreraise);
-
-         if assigned(right) then
-           begin
-              oldaktexitlabel:=aktexitlabel;
-              oldaktexit2label:=aktexit2label;
-              getlabel(exitonlabel);
-              aktexitlabel:=exitonlabel;
-              aktexit2label:=exitonlabel;
-              if assigned(aktbreaklabel) then
-               begin
-                 oldaktcontinuelabel:=aktcontinuelabel;
-                 oldaktbreaklabel:=aktbreaklabel;
-                 getlabel(breakonlabel);
-                 getlabel(continueonlabel);
-                 aktcontinuelabel:=continueonlabel;
-                 aktbreaklabel:=breakonlabel;
-               end;
-
-              { esi is destroyed by FPC_CATCHES }
-              maybe_loadself;
-              secondpass(right);
-           end;
-         getlabel(doobjectdestroy);
-         emitlab(doobjectdestroyandreraise);
-         emitcall('FPC_POPADDRSTACK');
-         ungetpersistanttempreference(tempaddr);
-         ungetpersistanttempreference(tempbuf);
-
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_EAX));
-         exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitjmp(C_E,doobjectdestroy);
-         emitcall('FPC_POPSECONDOBJECTSTACK');
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_DESTROYEXCEPTION');
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         { we don't need to restore esi here because reraise never }
-         { returns                                                 }
-         emitcall('FPC_RERAISE');
-
-         emitlab(doobjectdestroy);
-         cleanupobjectstack;
-         { clear some stuff }
-         ungetiftemp(ref);
-         emitjmp(C_None,endexceptlabel);
-
-         if assigned(right) then
-           begin
-              { special handling for control flow instructions }
-              if fc_exit in flowcontrol then
-                begin
-                   { the address and object pop does secondtryexcept }
-                   emitlab(exitonlabel);
-                   emitjmp(C_None,oldaktexitlabel);
-                end;
-
-              if fc_break in flowcontrol then
-                begin
-                   { the address and object pop does secondtryexcept }
-                   emitlab(breakonlabel);
-                   emitjmp(C_None,oldaktbreaklabel);
-                end;
-
-              if fc_continue in flowcontrol then
-                begin
-                   { the address and object pop does secondtryexcept }
-                   emitlab(continueonlabel);
-                   emitjmp(C_None,oldaktcontinuelabel);
-                end;
-
-              aktexitlabel:=oldaktexitlabel;
-              aktexit2label:=oldaktexit2label;
-              if assigned(oldaktbreaklabel) then
-               begin
-                 aktcontinuelabel:=oldaktcontinuelabel;
-                 aktbreaklabel:=oldaktbreaklabel;
-               end;
-           end;
-
-         emitlab(nextonlabel);
-         flowcontrol:=oldflowcontrol+flowcontrol;
-         { next on node }
-         if assigned(left) then
-           begin
-              cleartempgen;
-              secondpass(left);
-           end;
-      end;
-
-{*****************************************************************************
-                             SecondTryFinally
-*****************************************************************************}
-
-    procedure ti386tryfinallynode.pass_2;
-      var
-         reraiselabel,
-         finallylabel,
-         endfinallylabel,
-         exitfinallylabel,
-         continuefinallylabel,
-         breakfinallylabel,
-         oldaktexitlabel,
-         oldaktexit2label,
-         oldaktcontinuelabel,
-         oldaktbreaklabel : tasmlabel;
-         oldflowcontrol,tryflowcontrol : tflowcontrol;
-         decconst : longint;
-         tempbuf,tempaddr : treference;
-
-      begin
-         { check if child nodes do a break/continue/exit }
-         oldflowcontrol:=flowcontrol;
-         flowcontrol:=[];
-         { we modify EAX }
-         usedinproc:=usedinproc or ($80 shr byte(R_EAX));
-         getlabel(finallylabel);
-         getlabel(endfinallylabel);
-         getlabel(reraiselabel);
-
-         { the finally block must catch break, continue and exit }
-         { statements                                            }
-         oldaktexitlabel:=aktexitlabel;
-         oldaktexit2label:=aktexit2label;
-         getlabel(exitfinallylabel);
-         aktexitlabel:=exitfinallylabel;
-         aktexit2label:=exitfinallylabel;
-         if assigned(aktbreaklabel) then
-          begin
-            oldaktcontinuelabel:=aktcontinuelabel;
-            oldaktbreaklabel:=aktbreaklabel;
-            getlabel(breakfinallylabel);
-            getlabel(continuefinallylabel);
-            aktcontinuelabel:=continuefinallylabel;
-            aktbreaklabel:=breakfinallylabel;
-          end;
-
-         gettempofsizereferencepersistant(12,tempaddr);
-         gettempofsizereferencepersistant(24,tempbuf);
-         emitpushreferenceaddr(tempaddr);
-         emitpushreferenceaddr(tempbuf);
-         push_int(1); { Type of stack-frame must be pushed}
-         emitcall('FPC_PUSHEXCEPTADDR');
-
-         { allocate eax }
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emitcall('FPC_SETJMP');
-         emit_reg(A_PUSH,S_L,R_EAX);
-         emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
-         { deallocate eax }
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitjmp(C_NE,finallylabel);
-
-         { try code }
-         if assigned(left) then
-           begin
-              secondpass(left);
-              tryflowcontrol:=flowcontrol;
-              if codegenerror then
-                exit;
-           end;
-
-         emitlab(finallylabel);
-         emitcall('FPC_POPADDRSTACK');
-         ungetpersistanttempreference(tempaddr);
-         ungetpersistanttempreference(tempbuf);
-
-         { finally code }
-         flowcontrol:=[];
-         secondpass(right);
-         if flowcontrol<>[] then
-           CGMessage(cg_e_control_flow_outside_finally);
-         if codegenerror then
-           exit;
-         { allocate eax }
-         exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-         emit_reg(A_POP,S_L,R_EAX);
-         emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
-         emitjmp(C_E,endfinallylabel);
-         emit_reg(A_DEC,S_L,R_EAX);
-         emitjmp(C_Z,reraiselabel);
-         if fc_exit in tryflowcontrol then
-           begin
-              emit_reg(A_DEC,S_L,R_EAX);
-              emitjmp(C_Z,oldaktexitlabel);
-              decconst:=1;
-           end
-         else
-           decconst:=2;
-         if fc_break in tryflowcontrol then
-           begin
-              emit_const_reg(A_SUB,S_L,decconst,R_EAX);
-              emitjmp(C_Z,oldaktbreaklabel);
-              decconst:=1;
-           end
-         else
-           inc(decconst);
-         if fc_continue in tryflowcontrol then
-           begin
-              emit_const_reg(A_SUB,S_L,decconst,R_EAX);
-              emitjmp(C_Z,oldaktcontinuelabel);
-           end;
-         { deallocate eax }
-         exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-         emitlab(reraiselabel);
-         emitcall('FPC_RERAISE');
-         { do some magic for exit,break,continue in the try block }
-         if fc_exit in tryflowcontrol then
-           begin
-              emitlab(exitfinallylabel);
-              { allocate eax }
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emit_reg(A_POP,S_L,R_EAX);
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emit_const(A_PUSH,S_L,2);
-              emitjmp(C_NONE,finallylabel);
-           end;
-         if fc_break in tryflowcontrol then
-          begin
-             emitlab(breakfinallylabel);
-             { allocate eax }
-             exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-             emit_reg(A_POP,S_L,R_EAX);
-             { deallocate eax }
-             exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
-             emit_const(A_PUSH,S_L,3);
-             emitjmp(C_NONE,finallylabel);
-           end;
-         if fc_continue in tryflowcontrol then
-           begin
-              emitlab(continuefinallylabel);
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emit_reg(A_POP,S_L,R_EAX);
-              exprasmList.concat(Tairegalloc.Alloc(R_EAX));
-              emit_const(A_PUSH,S_L,4);
-              emitjmp(C_NONE,finallylabel);
-           end;
-
-         emitlab(endfinallylabel);
-
-         aktexitlabel:=oldaktexitlabel;
-         aktexit2label:=oldaktexit2label;
-         if assigned(aktbreaklabel) then
-          begin
-            aktcontinuelabel:=oldaktcontinuelabel;
-            aktbreaklabel:=oldaktbreaklabel;
-          end;
-         flowcontrol:=oldflowcontrol+tryflowcontrol;
-      end;
-
-
-{*****************************************************************************
-                             SecondFail
-*****************************************************************************}
-
-    procedure ti386failnode.pass_2;
-      begin
-        emitjmp(C_None,faillabel);
-      end;
-
-
-begin
-   cwhilerepeatnode:=ti386whilerepeatnode;
-   cifnode:=ti386ifnode;
-   cfornode:=ti386fornode;
-   cexitnode:=ti386exitnode;
-   cbreaknode:=ti386breaknode;
-   ccontinuenode:=ti386continuenode;
-   cgotonode:=ti386gotonode;
-   clabelnode:=ti386labelnode;
-   craisenode:=ti386raisenode;
-   ctryexceptnode:=ti386tryexceptnode;
-   ctryfinallynode:=ti386tryfinallynode;
-   connode:=ti386onnode;
-   cfailnode:=ti386failnode;
-end.
-{
-  $Log$
-  Revision 1.4  2001-09-09 17:10:25  jonas
-    * some more things implemented
-
-  Revision 1.3  2001/09/06 15:25:55  jonas
-    * changed type of tcg from object to class ->  abstract methods are now
-      a lot cleaner :)
-    + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
-      (if possible with geenric implementation and necessary ppc
-       implementations)
-    * worked a bit further on cgflw, now working on exitnode
-
-  Revision 1.2  2001/09/05 20:21:03  jonas
-    * new cgflow based on n386flw with all nodes until forn "translated"
-    + a_cmp_*_loc_label methods for tcg
-    + base implementatino for a_cmp_ref_*_label methods
-    * small bugfixes to powerpc cg
-
-
-}
-

+ 0 - 1396
compiler/new/cgobj.pas

@@ -1,1396 +0,0 @@
-{
-    $Id$
-    Copyright (c) 1998-2000 by Florian Klaempfl
-    Member of the Free Pascal development team
-
-    This unit implements the basic code generator object
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit cgobj;
-
-  interface
-
-    uses
-       cobjects,aasm,symtable,cpuasm,cpubase,cgbase,cpuinfo,tainst
-       symconst;
-
-    type
-       talignment = (AM_NATURAL,AM_NONE,AM_2BYTE,AM_4BYTE,AM_8BYTE);
-
-       tcg = class
-          scratch_register_array_pointer : aword;
-          unusedscratchregisters : tregisterset;
-
-          alignment : talignment;
-          {************************************************}
-          {                 basic routines                 }
-          constructor create;
-
-          procedure a_label(list : taasmoutput;l : pasmlabel);virtual;
-
-          { allocates register r by inserting a pai_realloc record }
-          procedure a_reg_alloc(list : taasmoutput;r : tregister);
-          { deallocates register r by inserting a pa_regdealloc record}
-          procedure a_reg_dealloc(list : taasmoutput;r : tregister);
-
-          { returns a register for use as scratch register }
-          function get_scratch_reg(list : taasmoutput) : tregister;
-          { releases a scratch register }
-          procedure free_scratch_reg(list : taasmoutput;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 : taasmoutput;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 : taasmoutput;t : pdef;const ref : treference;is_already_ref : boolean);
-
-          { helper routines }
-          procedure g_initialize_data(list : taasmoutput;p : psym);
-          procedure g_incr_data(list : taasmoutput;p : psym);
-          procedure g_finalize_data(list : taasmoutput;p : pnamedindexobject);
-          procedure g_copyvalueparas(list : taasmoutput;p : pnamedindexobject);
-          procedure g_finalizetempansistrings(list : taasmoutput);
-
-          procedure g_entrycode(list : taasmoutput;
-            const proc_names : tstringcontainer;make_global : boolean;
-            stackframe : longint;var parasize : longint;
-            var nostackframe : boolean;inlined : boolean);
-
-          procedure g_exitcode(list : taasmoutput;parasize : longint;
-            nostackframe,inlined : boolean);
-
-          { string helper routines }
-          procedure g_decrstrref(list : taasmoutput;const ref : treference;t : pdef);
-
-          procedure g_removetemps(list : taasmoutput;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 : taasmoutput;size : tcgsize;r : tregister;nr : longint);virtual; abstract;
-          procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);virtual;
-          procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);virtual;
-          procedure a_paramaddr_ref(list : taasmoutput;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
-          }
-
-          procedure a_call_name(list : taasmoutput;const s : string;
-            offset : longint);virtual;
-
-          { move instructions }
-          procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);virtual; abstract;
-          procedure a_load_const_ref(list : taasmoutput;size : tcgsize;a : aword;const ref : treference);virtual;
-          procedure a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);virtual; abstract;
-          procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);virtual; abstract;
-          procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);virtual; abstract;
-          procedure a_load_loc_reg(list : taasmoutput;size : tcgsize;const loc: tlocation; reg : tregister);
-
-
-          { basic arithmetic operations }
-          { note: for operators which require only one argument (not, neg), use }
-          { the op_reg_reg, op_reg_reg or op_reg_loc methods and keep in mind   }
-          { that in this case the *second* operand is used as both source and   }
-          { destination (JM)                                                    }
-          procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; reg: TRegister); virtual; abstract;
-          procedure a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const ref: TReference); virtual;
-          procedure a_op_const_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const loc: tloocation);
-          procedure a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister); virtual; abstract;
-          procedure a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; reg: TRegister; const ref: TReference); virtual;
-          procedure a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); virtual;
-          procedure a_op_reg_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; const loc: tloocation);
-          procedure a_op_ref_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; const loc: tloocation); virtual;
-
-          {  comparison operations }
-          procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
-            l : pasmlabel);virtual; abstract;
-          procedure a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference;
-            l : pasmlabel); virtual;
-          procedure a_cmp_const_loc_label(list: taasmoutput; size: tcgsiwe;cmp_op: topcmp; a: aword; const loc: tlocation;
-            l : pasmlabel); virtual;
-          procedure a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : pasmlabel); virtual; abstract;
-          procedure a_cmp_reg_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;reg : tregister; const ref: treference; l : pasmlabel); virtual;
-          procedure a_cmp_ref_loc_label(list: taasmoutput; size: tcgsiwe;cmp_op: topcmp; const ref: treference; const loc: tlocation;
-            l : pasmlabel); virtual;
-
-          procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: pasmlabel); abstract;
-
-          procedure g_flags2reg(list: taasmoutput; const f: TAsmCond; reg: TRegister); abstract;
-
-          procedure a_loadaddress_ref_reg(list : taasmoutput;const ref : treference;r : tregister);virtual; abstract;
-          procedure g_stackframe_entry(list : taasmoutput;localsize : longint);virtual; abstract;
-          { restores the frame pointer at procedure exit, for the }
-          { i386 it generates a simple leave                      }
-          procedure g_restore_frame_pointer(list : taasmoutput);virtual; abstract;
-
-          { 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 : taasmoutput;reg : tregister);virtual; abstract;
-          procedure g_push_exception_value_const(list : taasmoutput;reg : tregister);virtual; abstract;
-          { that procedure pops a exception value                             }
-          procedure g_pop_exception_value_reg(list : taasmoutput;reg : tregister);virtual; abstract;
-          procedure g_return_from_proc(list : taasmoutput;parasize : aword);virtual; abstract;
-          {********************************************************}
-          { these methods can be overriden for extra functionality }
-
-          { the following methods do nothing: }
-          procedure g_interrupt_stackframe_entry(list : taasmoutput);virtual;
-          procedure g_interrupt_stackframe_exit(list : taasmoutput);virtual;
-
-          procedure g_profilecode(list : taasmoutput);virtual; abstract;
-          procedure g_stackcheck(list : taasmoutput;stackframesize : longint);virtual; abstract;
-
-          procedure g_maybe_loadself(list : taasmoutput);virtual; abstract;
-          { 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 : taasmoutput;const source,dest : treference;len : aword;loadref : boolean);virtual; abstract;
-
-          { uses the addr of ref as param, was emitpushreferenceaddr }
-          procedure a_param_ref_addr(list : taasmoutput;r : treference;nr : longint);virtual; abstract;
-       end;
-
-    var
-       cg : pcg; { this is the main code generator class }
-
-  implementation
-
-    uses
-       strings,globals,globtype,options,files,gdb,systems,
-       ppu,verbose,types,tgobj,tgcpu
-       {$IFDEF NEWST}
-       ,symbols,defs,symtablt
-       {$ENDIF NEWST};
-
-{*****************************************************************************
-                            basic functionallity
-******************************************************************************}
-
-    constructor tcg.create;
-
-      var
-         i : longint;
-
-      begin
-         scratch_register_array_pointer:=1;
-         for i:=1 to max_scratch_regs do
-           include(unusedscratchregisters,scratch_regs[i]);
-      end;
-
-    procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
-
-      begin
-         list^.concat(new(pairegalloc,alloc(r)));
-      end;
-
-    procedure tcg.a_reg_dealloc(list : taasmoutput;r : tregister);
-
-      begin
-         list^.concat(new(pairegalloc,dealloc(r)));
-      end;
-
-    procedure tcg.a_label(list : taasmoutput;l : pasmlabel);
-
-      begin
-         list^.concat(new(pai_label,init(l)));
-      end;
-
-    function tcg.get_scratch_reg(list : taasmoutput) : tregister;
-
-      var
-         r : tregister;
-         i : longint;
-
-      begin
-         if unusedscratchregisters=[] then
-           internalerror(68996);
-
-         for i:=scratch_register_array_pointer to
-                (scratch_register_array_pointer+max_scratch_regs) do
-           if scratch_regs[(i mod max_scratch_regs)+1] in unusedscratchregisters then
-             begin
-                r:=scratch_regs[(i mod max_scratch_regs)+1];
-                break;
-             end;
-         exclude(unusedscratchregisters,r);
-         inc(scratch_register_array_pointer);
-         if scratch_register_array_pointer>max_scratch_regs then
-           scratch_register_array_pointer:=1;
-         a_reg_alloc(list,r);
-         get_scratch_reg:=r;
-      end;
-
-    procedure tcg.free_scratch_reg(list : taasmoutput;r : tregister);
-
-      begin
-         include(unusedscratchregisters,r);
-         a_reg_dealloc(list,r);
-      end;
-
-{*****************************************************************************
-            this methods must be overridden for extra functionality
-******************************************************************************}
-
-    procedure tcg.g_interrupt_stackframe_entry(list : taasmoutput);
-
-      begin
-      end;
-
-    procedure tcg.g_interrupt_stackframe_exit(list : taasmoutput);
-
-      begin
-      end;
-
-    procedure tcg.g_profilecode(list : taasmoutput);
-
-      begin
-      end;
-
-{*****************************************************************************
-          for better code generation these methods should be overridden
-******************************************************************************}
-
-    procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);
-
-      var
-         hr : tregister;
-
-      begin
-         hr:=get_scratch_reg(list);
-         a_load_const_reg(list,size,a,hr);
-         a_param_reg(list,size,hr,nr);
-         free_scratch_reg(list,hr);
-      end;
-
-    procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);
-
-      var
-         hr : tregister;
-
-      begin
-         hr:=get_scratch_reg(list);
-         a_load_ref_reg(list,size,r,hr);
-         a_param_reg(list,size,hr,nr);
-         free_scratch_reg(list,hr);
-      end;
-
-    procedure tcg.a_param_ref_addr(list : taasmoutput;const r : treference;nr : longint);
-
-      var
-         hr : tregister;
-
-      begin
-         hr:=get_scratch_reg(list);
-         a_loadaddress_ref_reg(list,r,hr);
-         a_param_reg(list,OS_ADDR,hr,nr);
-         free_scratch_reg(list,hr);
-      end;
-
-    procedure tcg.g_stackcheck(list : taasmoutput;stackframesize : longint);
-
-      begin
-         a_param_const(list,OS_32,stackframesize,1);
-         a_call_name(list,'FPC_STACKCHECK',0);
-      end;
-
-{*****************************************************************************
-                         String helper routines
-*****************************************************************************}
-
-    procedure tcg.g_removetemps(list : taasmoutput;p : plinkedlist);
-
-      var
-         hp : ptemptodestroy;
-         pushedregs : tpushed;
-
-      begin
-         hp:=ptemptodestroy(p^.first);
-         if not(assigned(hp)) then
-           exit;
-         tg.pushusedregisters(pushedregs,$ff);
-         while assigned(hp) do
-           begin
-              if is_ansistring(hp^.typ) then
-                begin
-                   g_decrstrref(list,hp^.address,hp^.typ);
-                   tg.ungetiftemp(hp^.address);
-                end;
-              hp:=ptemptodestroy(hp^.next);
-           end;
-         tg.popusedregisters(pushedregs);
-      end;
-
-    procedure tcg.g_decrstrref(list : taasmoutput;const ref : treference;t : pdef);
-
-      var
-         pushedregs : tpushed;
-
-      begin
-         tg.pushusedregisters(pushedregs,$ff);
-         a_param_ref_addr(list,ref,1);
-         if is_ansistring(t) then
-           a_call_name(list,'FPC_ANSISTR_DECR_REF',0)
-         else if is_widestring(t) then
-           a_call_name(list,'FPC_WIDESTR_DECR_REF',0)
-         else internalerror(58993);
-         tg.popusedregisters(pushedregs);
-      end;
-
-{*****************************************************************************
-                  Code generation for subroutine entry- and 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 tcg.g_initialize(list : taasmoutput;t : pdef;const ref : treference;is_already_ref : boolean);
-
-      var
-         hr : treference;
-
-      begin
-         if is_ansistring(t) or
-           is_widestring(t) then
-           a_load_const_ref(list,OS_8,0,ref)
-         else
-           begin
-              reset_reference(hr);
-              hr.symbol:=t^.get_inittable_label;
-              a_param_ref_addr(list,hr,2);
-              if is_already_ref then
-                a_param_ref(list,OS_ADDR,ref,1)
-              else
-                a_param_ref_addr(list,ref,1);
-              a_call_name(list,'FPC_INITIALIZE',0);
-           end;
-      end;
-
-    procedure tcg.g_finalize(list : taasmoutput;t : pdef;const ref : treference;is_already_ref : boolean);
-
-      var
-         r : treference;
-
-      begin
-         if is_ansistring(t) or
-           is_widestring(t) then
-           begin
-              g_decrstrref(list,ref,t);
-           end
-         else
-           begin
-              reset_reference(r);
-              r.symbol:=t^.get_inittable_label;
-              a_param_ref_addr(list,r,2);
-              if is_already_ref then
-                a_paramaddr_ref(list,ref,1)
-              else
-                a_param_ref_addr(list,ref,1);
-              a_call_name(list,'FPC_FINALIZE',0);
-           end;
-      end;
-
-    { generates the code for initialisation of local data }
-    procedure tcg.g_initialize_data(list : taasmoutput;p : psym);
-
-      var
-         hr : treference;
-
-      begin
-      {$IFDEF NEWST}
-         if (typeof(p^)=typeof(Tvarsym)) and
-            assigned(pvarsym(p)^.definition) and
-            not((typeof((pvarsym(p)^.definition^))=typeof(Tobjectdef)) and
-              (oo_is_class in pobjectdef(pvarsym(p)^.definition)^.options)) and
-            pvarsym(p)^.definition^.needs_inittable then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              if typeof((psym(p)^.owner^))=typeof(Tprocsymtable) then
-                begin
-                   hr.base:=procinfo^.framepointer;
-                   hr.offset:=-pvarsym(p)^.address;
-                end
-              else
-                begin
-                   hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-                end;
-              g_initialize(list,pvarsym(p)^.definition,hr,false);
-           end;
-      {$ELSE}
-         if (psym(p)^.typ=varsym) and
-            assigned(pvarsym(p)^.vartype.def) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-              pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              if psym(p)^.owner^.symtabletype=localsymtable then
-                begin
-                   hr.base:=procinfo^.framepointer;
-                   hr.offset:=-pvarsym(p)^.address;
-                end
-              else
-                begin
-                   hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-                end;
-              g_initialize(list,pvarsym(p)^.vartype.def,hr,false);
-           end;
-      {$ENDIF NEWST}
-      end;
-
-
-    { generates the code for incrementing the reference count of parameters }
-    procedure tcg.g_incr_data(list : taasmoutput;p : psym);
-
-      var
-         hr : treference;
-
-      begin
-      {$IFDEF NEWST}
-         if (typeof((psym(p)^))=typeof(Tparamsym)) and
-            not((typeof((Pparamsym(p)^.definition^))=typeof(Tobjectdef)) and
-              (oo_is_class in pobjectdef(pvarsym(p)^.definition)^.options)) and
-            Pparamsym(p)^.definition^.needs_inittable and
-            ((Pparamsym(p)^.varspez=vs_value)) then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              hr.symbol:=pvarsym(p)^.definition^.get_inittable_label;
-              a_param_ref_addr(list,hr,2);
-              reset_reference(hr);
-              hr.base:=procinfo^.framepointer;
-              hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-              a_param_ref_addr(list,hr,1);
-              reset_reference(hr);
-              a_call_name(list,'FPC_ADDREF',0);
-           end;
-      {$ELSE}
-         if (psym(p)^.typ=varsym) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-              pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable and
-            ((pvarsym(p)^.varspez=vs_value)) then
-           begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              hr.symbol:=pvarsym(p)^.vartype.def^.get_inittable_label;
-              a_param_ref_addr(list,hr,2);
-              reset_reference(hr);
-              hr.base:=procinfo^.framepointer;
-              hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-              a_param_ref_addr(list,hr,1);
-              reset_reference(hr);
-              a_call_name(list,'FPC_ADDREF',0);
-           end;
-      {$ENDIF NEWST}
-      end;
-
-
-    { generates the code for finalisation of local data }
-    procedure tcg.g_finalize_data(list : taasmoutput;p : pnamedindexobject);
-
-      var
-         hr : treference;
-
-      begin
-      {$IFDEF NEWST}
-         if (typeof((psym(p)^))=typeof(Tvarsym)) and
-            assigned(pvarsym(p)^.definition) and
-            not((typeof((pvarsym(p)^.definition^))=typeof(Tobjectdef)) and
-            (oo_is_class in pobjectdef(pvarsym(p)^.definition)^.options)) and
-            pvarsym(p)^.definition^.needs_inittable then
-           begin
-              { not all kind of parameters need to be finalized  }
-              if (typeof((psym(p)^.owner^))=typeof(Tprocsymtable)) and
-                ((pparamsym(p)^.varspez=vs_var)  or
-                 (Pparamsym(p)^.varspez=vs_const) { and
-                 (dont_copy_const_param(pvarsym(p)^.definition)) } ) then
-                exit;
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              if typeof((Psym(p)^.owner^))=typeof(Tprocsymtable) then
-                 begin
-                    hr.base:=procinfo^.framepointer;
-                    hr.offset:=-pvarsym(p)^.address;
-                 end
-              else if typeof((Psym(p)^.owner^))=typeof(Tprocsymtable) then
-                 begin
-                    hr.base:=procinfo^.framepointer;
-                    hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-                 end
-               else
-                 hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-              g_finalize(list,pvarsym(p)^.definition,hr,false);
-           end;
-      {$ELSE}
-         if (psym(p)^.typ=varsym) and
-            assigned(pvarsym(p)^.vartype.def) and
-            not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-            pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-            pvarsym(p)^.vartype.def^.needs_inittable then
-           begin
-              { not all kind of parameters need to be finalized  }
-              if (psym(p)^.owner^.symtabletype=parasymtable) and
-                ((pvarsym(p)^.varspez=vs_var)  or
-                 (pvarsym(p)^.varspez=vs_const) { and
-                 (dont_copy_const_param(pvarsym(p)^.definition)) } ) then
-                exit;
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              reset_reference(hr);
-              case psym(p)^.owner^.symtabletype of
-                 localsymtable:
-                   begin
-                      hr.base:=procinfo^.framepointer;
-                      hr.offset:=-pvarsym(p)^.address;
-                   end;
-                 parasymtable:
-                   begin
-                      hr.base:=procinfo^.framepointer;
-                      hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-                   end;
-                 else
-                   hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
-              end;
-              g_finalize(list,pvarsym(p)^.vartype.def,hr,false);
-           end;
-      {$ENDIF NEWST}
-      end;
-
-
-    { generates the code to make local copies of the value parameters }
-    procedure tcg.g_copyvalueparas(list : taasmoutput;p : pnamedindexobject);
-      begin
-         runerror(255);
-      end;
-
-    var
-       _list : taasmoutput;
-
-    { wrappers for the methods, because TP doesn't know procedures }
-    { of objects                                                   }
-
-    {$IFNDEF NEWST}
-    procedure _copyvalueparas(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_copyvalueparas(_list,s);
-      end;
-    {$ENDIF NEWST}
-
-    procedure tcg.g_finalizetempansistrings(list : taasmoutput);
-
-      var
-         hp : ptemprecord;
-         hr : treference;
-
-      begin
-         hp:=tg.templist;
-         while assigned(hp) do
-           begin
-              if hp^.temptype in [tt_ansistring,tt_freeansistring] then
-                begin
-                   procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-                   reset_reference(hr);
-                   hr.base:=procinfo^.framepointer;
-                   hr.offset:=hp^.pos;
-                   a_param_ref_addr(list,hr,1);
-                   a_call_name(list,'FPC_ANSISTR_DECR_REF',0);
-                end;
-              hp:=hp^.next;
-           end;
-     end;
-
- {$IFDEF NEWST}
-    procedure _initialize_local(s:Pnamedindexobject);{$IFNDEF FPC}far;{$ENDIF}
-
-    begin
-        if typeof(s^)=typeof(Tparamsym) then
-            cg^.g_incr_data(_list,Psym(s))
-        else
-            cg^.g_initialize_data(_list,Psym(s));
-    end;
-
-    procedure _finalize_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
-
-    begin
-        if typeof(s^)=typeof(Tvarsym) then
-            cg^.g_finalize_data(_list,s);
-    end;
-
- {$ELSE}
-    procedure _finalize_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_finalize_data(_list,s);
-      end;
-
-    procedure _incr_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_incr_data(_list,psym(s));
-      end;
-
-    procedure _initialize_data(s : pnamedindexobject);{$ifndef FPC}far;{$endif}
-
-      begin
-         cg^.g_initialize_data(_list,psym(s));
-      end;
- {$ENDIF NEWST}
-
-    { generates the entry code for a procedure }
-    procedure tcg.g_entrycode(list : taasmoutput;const proc_names:Tstringcontainer;make_global:boolean;
-       stackframe:longint;var parasize:longint;var nostackframe:boolean;
-       inlined : boolean);
-
-
-    {$IFDEF NEWST}
-        procedure _copyvalueparas(s:Pparamsym);{$ifndef FPC}far;{$endif}
-
-        begin
-            cg^.g_copyvalueparas(_list,s);
-        end;
-    {$ENDIF NEWST}
-
-      var
-         hs : string;
-         hp : pused_unit;
-         initcode : taasmoutput;
-{$ifdef GDB}
-         stab_function_name : Pai_stab_function_name;
-{$endif GDB}
-         hr : treference;
-         r : tregister;
-
-      begin
-         { Align }
-         if (not inlined) then
-           begin
-              { gprof uses 16 byte granularity !! }
-              if (cs_profile in aktmoduleswitches) then
-                list^.insert(new(pai_align,init(16)))
-              else
-                if not(cs_littlesize in aktglobalswitches) then
-                  list^.insert(new(pai_align,init(4)));
-          end;
-         { save registers on cdecl }
-         {$IFDEF NEWST}
-         if (posavestdregs in aktprocdef^.options) then
-         {$ELSE}
-         if (po_savestdregs in aktprocsym^.definition^.procoptions) then
-         {$ENDIF NEWST}
-           begin
-              for r:=firstreg to lastreg do
-                begin
-                   if (r in registers_saved_on_cdecl) then
-                     if (r in (tg.availabletempregsint+
-                               tg.availabletempregsfpu+
-                               tg.availabletempregsmm)) then
-                       begin
-                          if not(r in tg.usedinproc) then
-                            {!!!!!!!!!!!! a_push_reg(list,r) }
-                       end
-                     else
-                       {!!!!!!!! a_push_reg(list,r) };
-                end;
-           end;
-        { omit stack frame ? }
-        if not inlined then
-          if procinfo^.framepointer=stack_pointer then
-            begin
-               CGMessage(cg_d_stackframe_omited);
-               nostackframe:=true;
-            {$IFDEF NEWST}
-               if (aktprocdef^.proctype in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocdef^.localst^.paramdatasize+procinfo^.para_offset-pointersize;
-            {$ELSE}
-               if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocsym^.definition^.parast^.datasize+procinfo^.para_offset-pointersize;
-            {$ENDIF NEWST}
-            end
-          else
-            begin
-            {$IFDEF NEWST}
-               if (aktprocdef^.proctype in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocdef^.localst^.paramdatasize+procinfo^.para_offset-pointersize*2;
-            {$ELSE}
-               if (aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
-                 parasize:=0
-               else
-                 parasize:=aktprocsym^.definition^.parast^.datasize+procinfo^.para_offset-pointersize*2;
-            {$ENDIF}
-               nostackframe:=false;
-            {$IFDEF NEWST}
-               if (pointerrupt in aktprocdef^.options) then
-                 g_interrupt_stackframe_entry(list);
-            {$ELSE}
-               if (po_interrupt in aktprocsym^.definition^.procoptions) then
-                 g_interrupt_stackframe_entry(list);
-            {$ENDIF NEWST}
-
-               g_stackframe_entry(list,stackframe);
-
-               if (cs_check_stack in aktlocalswitches) and
-                 (tf_supports_stack_checking in target_info.flags) then
-                 g_stackcheck(@initcode,stackframe);
-            end;
-
-         if cs_profile in aktmoduleswitches then
-           g_profilecode(@initcode);
-         {$IFDEF NEWST}
-          if (not inlined) and (aktprocdef^.proctype in [potype_unitinit]) then
-         {$ELSE}
-          if (not inlined) and (aktprocsym^.definition^.proctypeoption in [potype_unitinit]) then
-         {$ENDIF NEWST}
-            begin
-
-              { needs the target a console flags ? }
-              if tf_needs_isconsole in target_info.flags then
-                begin
-                   hr.symbol:=newasmsymbol('U_'+target_info.system_unit+'_ISCONSOLE');
-                   if apptype=at_cui then
-                     a_load_const_ref(list,OS_8,1,hr)
-                   else
-                     a_load_const_ref(list,OS_8,0,hr);
-                   dispose(hr.symbol,done);
-                end;
-
-              hp:=pused_unit(usedunits.first);
-              while assigned(hp) do
-                begin
-                   { call the unit init code and make it external }
-                   if (hp^.u^.flags and uf_init)<>0 then
-                     a_call_name(list,
-                       'INIT$$'+hp^.u^.modulename^,0);
-                    hp:=Pused_unit(hp^.next);
-                end;
-           end;
-
-{$ifdef dummy}
-         { a constructor needs a help procedure }
-         if (aktprocsym^.definition^.options and poconstructor)<>0 then
-           begin
-             if procinfo^._class^.isclass then
-               begin
-                 list^.concat(new(paicpu,op_sym(A_CALL,S_NO,newasmsymbol('FPC_NEW_CLASS'))));
-                 list^.concat(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,quickexitlabel)));
-               end
-             else
-               begin
-                 {
-                 list^.insert(new(pai_labeled,init(A_JZ,quickexitlabel)));
-                 list^.insert(new(paicpu,op_csymbol(A_CALL,S_NO,
-                   newcsymbol('FPC_HELP_CONSTRUCTOR',0))));
-                 list^.insert(new(paicpu,op_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI)));
-                 concat_external('FPC_HELP_CONSTRUCTOR',EXT_NEAR);
-                 }
-               end;
-           end;
-{$endif dummy}
-  {$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) then
-           list^.insert(new(pai_force_line,init));
-  {$endif GDB}
-
-        {$IFDEF NEWST}
-         { initialize return value }
-         if assigned(procinfo^.retdef) and
-           is_ansistring(procinfo^.retdef) or
-           is_widestring(procinfo^.retdef) then
-           begin
-              reset_reference(hr);
-              hr.offset:=procinfo^.return_offset;
-              hr.base:=procinfo^.framepointer;
-              a_load_const_ref(list,OS_32,0,hr);
-           end;
-        {$ELSE}
-         { initialize return value }
-         if assigned(procinfo^.returntype.def) and
-           is_ansistring(procinfo^.returntype.def) or
-           is_widestring(procinfo^.returntype.def) then
-           begin
-              reset_reference(hr);
-              hr.offset:=procinfo^.return_offset;
-              hr.base:=procinfo^.framepointer;
-              a_load_const_ref(list,OS_32,0,hr);
-           end;
-        {$ENDIF}
-
-         _list:=list;
-         { generate copies of call by value parameters }
-        {$IFDEF NEWST}
-         if (poassembler in aktprocdef^.options) then
-            aktprocdef^.parameters^.foreach(@_copyvalueparas);
-        {$ELSE}
-         if (po_assembler in aktprocsym^.definition^.procoptions) then
-            aktprocsym^.definition^.parast^.foreach({$ifdef FPC}@{$endif FPC}_copyvalueparas);
-        {$ENDIF NEWST}
-
-        {$IFDEF NEWST}
-         { initialisizes local data }
-         aktprocdef^.localst^.foreach({$ifdef FPC}@{$endif FPC}_initialize_local);
-        {$ELSE}
-         { initialisizes local data }
-         aktprocsym^.definition^.localst^.foreach({$ifdef FPC}@{$endif FPC}_initialize_data);
-         { add a reference to all call by value/const parameters }
-         aktprocsym^.definition^.parast^.foreach({$ifdef FPC}@{$endif FPC}_incr_data);
-        {$ENDIF NEWST}
-
-        {$IFDEF NEWST}
-         if (cs_profile in aktmoduleswitches) or
-           (typeof(aktprocdef^.owner^)=typeof(Tglobalsymtable)) or
-           (typeof(aktprocdef^.owner^)=typeof(Timplsymtable)) or
-           (assigned(procinfo^._class) and
-           (typeof(procinfo^._class^.owner^)=typeof(Tglobalsymtable)) or
-           (typeof(procinfo^._class^.owner^)=typeof(Timplsymtable))) then
-           make_global:=true;
-        {$ELSE}
-         if (cs_profile in aktmoduleswitches) or
-           (aktprocsym^.definition^.owner^.symtabletype=globalsymtable) or
-           (assigned(procinfo^._class) and (procinfo^._class^.owner^.symtabletype=globalsymtable)) then
-           make_global:=true;
-        {$ENDIF NEWST}
-         if not inlined then
-           begin
-              hs:=proc_names.get;
-
-  {$ifdef GDB}
-              if (cs_debuginfo in aktmoduleswitches) and target_os.use_function_relative_addresses then
-                stab_function_name := new(pai_stab_function_name,init(strpnew(hs)));
-  {$endif GDB}
-
-              { insert the names for the procedure }
-              while hs<>'' do
-                begin
-                   if make_global then
-                     exprasmlist^.insert(new(pai_symbol,initname_global(hs,0)))
-                   else
-                     exprasmlist^.insert(new(pai_symbol,initname(hs,0)));
-
-  {$ifdef GDB}
-                   if (cs_debuginfo in aktmoduleswitches) then
-                     begin
-                       if target_os.use_function_relative_addresses then
-                         list^.insert(new(pai_stab_function_name,init(strpnew(hs))));
-                    end;
-  {$endif GDB}
-
-                  hs:=proc_names.get;
-               end;
-          end;
-
-  {$ifdef GDB}
-         if (not inlined) and (cs_debuginfo in aktmoduleswitches) then
-           begin
-              if target_os.use_function_relative_addresses then
-                  list^.insert(stab_function_name);
-              if make_global or ((procinfo^.flags and pi_is_global) <> 0) then
-                  aktprocsym^.is_global := True;
-              list^.insert(new(pai_stabs,init(aktprocsym^.stabstring)));
-              aktprocsym^.isstabwritten:=true;
-            end;
-  {$endif GDB}
-    end;
-
-    procedure tcg.g_exitcode(list : taasmoutput;parasize:longint;nostackframe,inlined:boolean);
-
-      var
-  {$ifdef GDB}
-         mangled_length : longint;
-         p : pchar;
-  {$endif GDB}
-         nofinal,noreraiselabel : pasmlabel;
-         hr : treference;
-         r : tregister;
-
-      begin
-         if aktexitlabel^.is_used then
-           list^.insert(new(pai_label,init(aktexitlabel)));
-
-         { call the destructor help procedure }
-         {$IFDEF NEWST}
-         if (aktprocdef^.proctype=potype_destructor) then
-         {$ELSE}
-         if (aktprocsym^.definition^.proctypeoption=potype_destructor) then
-         {$ENDIF}
-           begin
-           {$IFDEF NEWST}
-             if oo_is_class in procinfo^._class^.options then
-           {$ELSE NEWST}
-             if procinfo^._class^.is_class then
-           {$ENDIF}
-               a_call_name(list,'FPC_DISPOSE_CLASS',0)
-             else
-               begin
-                  if procinfo^._class^.needs_inittable then
-                    begin
-                       getlabel(nofinal);
-                       {!!!!!!!!!!
-                       reset_reference(hr);
-                       hr.base:=R_EBP;
-                       hr.offset:=8;
-                       a_cmp_reg_const_label(list,OS_ADDR,OZ_EQ,
-                       }
-                       reset_reference(hr);
-                       hr.symbol:=procinfo^._class^.get_inittable_label;
-                       a_paramaddr_ref(list,hr,2);
-                       a_param_reg(list,OS_ADDR,self_pointer,1);
-                       a_call_name(list,'FPC_FINALIZE',0);
-                       a_label(list,nofinal);
-                    end;
-                  { vmt_offset_reg can be a scratch register, }
-                  { but it must be always the same            }
-                  a_reg_alloc(list,vmt_offset_reg);
-                  a_load_const_reg(list,OS_32,procinfo^._class^.vmt_offset,vmt_offset_reg);
-                  a_call_name(list,'FPC_HELP_DESTRUCTOR',0);
-                  a_reg_dealloc(list,vmt_offset_reg);
-               end;
-           end;
-
-         { finalize temporary data }
-         g_finalizetempansistrings(list);
-
-         _list:=list;
-
-         { finalize local data }
-         {$IFDEF NEWST}
-         aktprocdef^.localst^.foreach({$ifndef TP}@{$endif}_finalize_data);
-         {$ELSE}
-         aktprocsym^.definition^.localst^.foreach({$ifndef TP}@{$endif}_finalize_data);
-         {$ENDIF}
-
-         {$IFNDEF NEWST}
-         { finalize paras data }
-         if assigned(aktprocsym^.definition^.parast) then
-           aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}_finalize_data);
-         {$ENDIF NEWST}
-
-         { do we need to handle exceptions because of ansi/widestrings ? }
-         if (procinfo^.flags and pi_needs_implicit_finally)<>0 then
-           begin
-              getlabel(noreraiselabel);
-
-              a_call_name(list,'FPC_POPADDRSTACK',0);
-              a_reg_alloc(list,accumulator);
-              g_pop_exception_value_reg(list,accumulator);
-              a_cmp_const_reg_label(list,OS_32,OC_EQ,0,accumulator,noreraiselabel);
-              a_reg_dealloc(list,accumulator);
-
-           {$IFDEF NEWST}
-              { must be the return value finalized before reraising the exception? }
-              if (procinfo^.retdef<>pdef(voiddef)) and
-                (procinfo^.retdef^.needs_inittable) and
-                ((typeof(procinfo^.retdef^)<>typeof(Tobjectdef)) or
-                not(oo_is_class in pobjectdef(procinfo^.retdef)^.options)) then
-                begin
-                   reset_reference(hr);
-                   hr.offset:=procinfo^.return_offset;
-                   hr.base:=procinfo^.framepointer;
-                   g_finalize(list,procinfo^.retdef,hr,not (dp_ret_in_acc in procinfo^.retdef^.properties));
-                end;
-           {$ELSE}
-              { must be the return value finalized before reraising the exception? }
-              if (procinfo^.returntype.def<>pdef(voiddef)) and
-                (procinfo^.returntype.def^.needs_inittable) and
-                ((procinfo^.returntype.def^.deftype<>objectdef) or
-                not(pobjectdef(procinfo^.returntype.def)^.is_class)) then
-                begin
-                   reset_reference(hr);
-                   hr.offset:=procinfo^.return_offset;
-                   hr.base:=procinfo^.framepointer;
-                   g_finalize(list,procinfo^.returntype.def,hr,ret_in_param(procinfo^.returntype.def));
-                end;
-           {$ENDIF}
-
-              a_call_name(list,'FPC_RERAISE',0);
-              a_label(list,noreraiselabel);
-           end;
-
-         { call __EXIT for main program }
-      {$IFDEF NEWST}
-         if (not DLLsource) and (not inlined) and (aktprocdef^.proctype=potype_proginit) then
-           a_call_name(list,'FPC_DO_EXIT',0);
-      {$ELSE}
-         if (not DLLsource) and (not inlined) and (aktprocsym^.definition^.proctypeoption=potype_proginit) then
-           a_call_name(list,'FPC_DO_EXIT',0);
-      {$ENDIF NEWST}
-
-         { handle return value }
-      {$IFDEF NEWST}
-         if not(poassembler in aktprocdef^.options) then
-             if (aktprocdef^.proctype<>potype_constructor) then
-      {$ELSE}
-         if not(po_assembler in aktprocsym^.definition^.procoptions) then
-             if (aktprocsym^.definition^.proctypeoption<>potype_constructor) then
-      {$ENDIF NEWST}
-               { handle_return_value(inlined) }
-             else
-               begin
-                  { return self in EAX }
-                  a_label(list,quickexitlabel);
-                  a_reg_alloc(list,accumulator);
-                  a_load_reg_reg(list,OS_ADDR,self_pointer,accumulator);
-                  a_reg_dealloc(list,self_pointer);
-                  a_label(list,quickexitlabel);
-                  { we can't clear the zero flag because the Alpha     }
-                  { for example doesn't have flags, we have to compare }
-                  { the accu. in the caller                            }
-               end;
-
-         { stabs uses the label also ! }
-         if aktexit2label^.is_used or
-            ((cs_debuginfo in aktmoduleswitches) and not inlined) then
-           a_label(list,aktexit2label);
-
-{$ifdef dummy}
-         { should we restore edi ? }
-         { for all i386 gcc implementations }
-         {!!!!!!!!!!! I don't know how to handle register saving yet }
-         if (po_savestdregs in aktprocsym^.definition^.procoptions) then
-           begin
-             if (aktprocsym^.definition^.usedregisters and ($80 shr byte(R_EBX)))<>0 then
-              exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_EBX)));
-             exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_ESI)));
-             exprasmlist^.concat(new(paicpu,op_reg(A_POP,S_L,R_EDI)));
-             { here we could reset R_EBX
-               but that is risky because it only works
-               if genexitcode is called after genentrycode
-               so lets skip this for the moment PM
-             aktprocsym^.definition^.usedregisters:=
-               aktprocsym^.definition^.usedregisters or not ($80 shr byte(R_EBX));
-             }
-           end;
-{$endif dummy}
-         if not(nostackframe) and not inlined then
-           g_restore_frame_pointer(list);
-         { at last, the return is generated }
-
-         if not inlined then
-         {$IFDEF NEWST}
-           if pointerrupt in aktprocdef^.options then
-         {$ELSE}
-           if po_interrupt in aktprocsym^.definition^.procoptions then
-         {$ENDIF NEWST}
-             g_interrupt_stackframe_exit(list)
-         else
-           g_return_from_proc(list,parasize);
-    {$IFDEF NEWST}
-         list^.concat(new(pai_symbol_end,initname(aktprocdef^.mangledname)));
-    {$ELSE NEWST}
-         list^.concat(new(pai_symbol_end,initname(aktprocsym^.definition^.mangledname)));
-    {$ENDIF NEWST}
-
-    {$ifdef GDB}
-         if (cs_debuginfo in aktmoduleswitches) and not inlined  then
-             begin
-                aktprocsym^.concatstabto(list);
-                if assigned(procinfo^._class) then
-                  if (not assigned(procinfo^.parent) or
-                     not assigned(procinfo^.parent^._class)) then
-                    list^.concat(new(pai_stabs,init(strpnew(
-                     '"$t:v'+procinfo^._class^.numberstring+'",'+
-                     tostr(N_PSYM)+',0,0,'+tostr(procinfo^.selfpointer_offset)))));
-                  {!!!!!!!!!!!!
-                  else
-                    list^.concat(new(pai_stabs,init(strpnew(
-                     '"$t:r'+procinfo^._class^.numberstring+'",'+
-                     tostr(N_RSYM)+',0,0,'+tostr(GDB_i386index[R_ESI])))));
-                  }
-                if (pdef(aktprocsym^.definition^.rettype.def) <> pdef(voiddef)) then
-                  begin
-                    if ret_in_param(aktprocsym^.definition^.rettype.def) then
-                      list^.concat(new(pai_stabs,init(strpnew(
-                       '"'+aktprocsym^.name+':X*'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                       tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))))
-                    else
-                      list^.concat(new(pai_stabs,init(strpnew(
-                       '"'+aktprocsym^.name+':X'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                       tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))));
-                    if (m_result in aktmodeswitches) then
-                      if ret_in_param(aktprocsym^.definition^.rettype.def) then
-                        list^.concat(new(pai_stabs,init(strpnew(
-                         '"RESULT:X*'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                         tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))))
-                      else
-                        list^.concat(new(pai_stabs,init(strpnew(
-                         '"RESULT:X'+aktprocsym^.definition^.rettype.def^.numberstring+'",'+
-                         tostr(N_PSYM)+',0,0,'+tostr(procinfo^.return_offset)))));
-                  end;
-                mangled_length:=length(aktprocsym^.definition^.mangledname);
-                getmem(p,mangled_length+50);
-                strpcopy(p,'192,0,0,');
-                strpcopy(strend(p),aktprocsym^.definition^.mangledname);
-                list^.concat(new(pai_stabn,init(strnew(p))));
-                {list^.concat(new(pai_stabn,init(strpnew('192,0,0,'
-                 +aktprocsym^.definition^.mangledname))));
-                p[0]:='2';p[1]:='2';p[2]:='4';
-                strpcopy(strend(p),'_end');}
-                freemem(p,mangled_length+50);
-                list^.concat(new(pai_stabn,init(
-                  strpnew('224,0,0,'+aktexit2label^.name))));
-                 { strpnew('224,0,0,'
-                 +aktprocsym^.definition^.mangledname+'_end'))));}
-             end;
-    {$endif GDB}
-      end;
-
-{*****************************************************************************
-                       some generic implementations
- ****************************************************************************}
-
-
-    procedure tcg.a_load_const_ref(list : taasmoutput;size : tcgsize;a : aword;const ref : treference);
-
-    var
-      tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_const_reg(list,size,a,tmpreg);
-        a_load_reg_ref(list,size,tmpref,ref);
-        free_scratch_reg(list,tmpreg);
-      end;
-
-    procedure tcg.a_load_loc_reg(list : taasmoutput;size : tcgsize;const loc: tlocation; reg : tregister);
-
-      begin
-        case loc.loc of
-          LOC_REFERENCE,LOC_MEM:
-            a_load_ref_reg(list,size,loc.reference,reg);
-          LOC_REGISTER,LOC_CREGISTER:
-            a_load_reg_reg(lost,size,loc.register,reg);
-          else
-            internalerror(200109092);
-        end;
-      end;
-
-
-    procedure tcg.a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const ref: TReference);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_ref_reg(list,size,ref,tmpreg);
-        a_op_const_reg(list,op,size,a,tmpreg);
-        a_load_reg_ref(list,size,tmpreg,ref);
-        free_scratch_reg(tmpreg);
-      end;
-
-
-    procedure tcg.a_op_const_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; const loc: tloocation);
-
-      begin
-        case loc.loc of
-          LOC_REGISTER, LOC_CREGISTER:
-            a_op_const_reg(list,op,size,a,loc.register);
-          LOC_REFERENCE, LOC_MEM:
-            a_op_const_reg(list,op,size,a,loc.reference);
-          else
-            internalerror(200109061);
-      end;
-
-
-    procedure tcg.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister;  const ref: TReference);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_ref_reg(list,size,ref,tmpreg);
-        a_op_reg_reg(list,op,size,reg,tmpreg);
-        a_load_reg_ref(list,size,tmpreg,ref);
-        free_scratch_reg(tmpreg);
-      end;
-
-
-    procedure tcg.a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); virtual;
-      var
-        tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_ref_reg(list,size,ref,tmpreg);
-        a_op_reg_reg(list,op,size,tmpreg,reg);
-        free_scratch_reg(tmpreg);
-      end;
-
-
-    procedure tcg.a_op_reg_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; const loc: tloocation);
-
-      begin
-        case loc.loc of
-          LOC_REGISTER, LOC_CREGISTER:
-            a_op_reg_reg(list,op,size,a,loc.register);
-          LOC_REFERENCE, LOC_MEM:
-            a_op_reg_ref(list,op,size,a,loc.reference);
-          else
-            internalerror(200109061);
-      end;
-
-
-    procedure tcg.a_op_ref_loc(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; const loc: tloocation);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        case loc.loc of
-          LOC_REGISTER,LOC_CREGISTER:
-            a_op_ref_reg(list,op,size,ref,loc.register,l);
-          LOC_REFERENCE,LOC_MEM:
-            begin
-              tmpreg := get_scratch_reg(list);
-              a_load_ref_reg(size,reftmpreg);
-              a_op_reg_ref(list,op,size,tmpreg,location.reference);
-              free_scratch_reg(list,tmpreg);
-            end;
-          else
-            internalerror(200109061);
-        end;
-      end;
-
-
-    procedure tcg.a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference;
-     l : pasmlabel);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_ref_reg(list,size,ref,tmpreg);
-        a_cmp_const_reg_label(list,size,cmp_op,a,tmpreg,l);
-        free_scratch_reg(tmpreg);
-      end;
-
-    procedure tcg.a_cmp_const_loc_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const loc : tlocation;
-      l : pasmlabel);
-
-      begin
-        case loc.loc of
-          LOC_REGISTER,LOC_CREGISTER:
-            a_cmp_const_reg_label(list,size,cmp_op,a,loc.register,l);
-          LOC_REFERENCE,LOC_MEM:
-            a_cmp_const_ref_label(list,size,cmp_op,a,loc.reference,l);
-          else
-            internalerror(200109061);
-        end;
-      end;
-
-    procedure tcg.a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp; const ref: treference; reg : tregister; l : pasmlabel);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        tmpreg := get_scratch_reg(list);
-        a_load_ref_reg(list,size,ref,tmpreg);
-        a_cmp_reg_reg_label(list,size,cmp_op,a,tmpreg,l);
-        free_scratch_reg(tmpreg);
-      end;
-
-    procedure tcg.a_cmp_ref_loc_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference;const loc : tlocation;
-      l : pasmlabel);
-
-      var
-        tmpreg: tregister;
-
-      begin
-        case loc.loc of
-          LOC_REGISTER,LOC_CREGISTER:
-            { we reverse the operands, so also do the inverse comparison }
-            a_cmp_reg_ref_label(list,size,inverse_opcmp(cmp_op),loc.register,ref,l);
-          LOC_REFERENCE,LOC_MEM:
-            begin
-              tmpreg := get_scratch_reg(list);
-              a_load_ref_reg(size,reftmpreg);
-              a_cmp_reg_ref(list,size,cmp_op,tmpreg,location.reference,l);
-              free_scratch_reg(list,tmpreg);
-            end;
-          else
-            internalerror(200109061);
-        end;
-      end;
-
-end.
-{
-  $Log$
-  Revision 1.5  2001-09-09 17:10:26  jonas
-    * some more things implemented
-
-  Revision 1.4  2001/09/06 15:25:55  jonas
-    * changed type of tcg from object to class ->  abstract methods are now
-      a lot cleaner :)
-    + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
-      (if possible with geenric implementation and necessary ppc
-       implementations)
-    * worked a bit further on cgflw, now working on exitnode
-
-  Revision 1.3  2001/09/05 20:21:03  jonas
-    * new cgflow based on n386flw with all nodes until forn "translated"
-    + a_cmp_loc_*_label methods for tcg
-    + base implementatino for a_cmp_ref_*_label methods
-    * small bugfixes to powerpc cg
-
-  Revision 1.2  2001/08/26 13:37:04  florian
-    * some cg reorganisation
-    * some PPC updates
-
-  Revision 1.1  2000/07/13 06:30:07  michael
-    + Initial import
-
-}