mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 01:11:29 +01:00 
			
		
		
		
	* spilling code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs
    to be added.
  * Spilling fixed when both operands needed to be spilled
  * Cleanup of spilling routine, do_spill_readwritten removed
			
			
This commit is contained in:
		
							parent
							
								
									ec720a5800
								
							
						
					
					
						commit
						ee3585f56f
					
				| @ -140,7 +140,7 @@ begin | ||||
|               end | ||||
|       end; | ||||
|     else | ||||
|       for opCount := 1 to MaxCh do | ||||
|       for opCount := 1 to maxinschanges do | ||||
|         case InsProp[p.opcode].Ch[opCount] of | ||||
|           Ch_MOp1,CH_WOp1,CH_RWOp1: | ||||
|               if not(onlymem) or | ||||
| @ -904,7 +904,7 @@ begin | ||||
|       begin | ||||
|         NoHardCodedRegs := true; | ||||
|         with InsProp[p.opcode] do | ||||
|           for chCount := 1 to MaxCh do | ||||
|           for chCount := 1 to maxinschanges do | ||||
|             if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then | ||||
|               begin | ||||
|                 NoHardCodedRegs := false; | ||||
| @ -1058,7 +1058,7 @@ begin | ||||
| {                updateStates(orgReg,newReg,p,false);} | ||||
|                 doReplaceReadReg := true; | ||||
|               end; | ||||
|         for opCount := 1 to MaxCh do | ||||
|         for opCount := 1 to maxinschanges do | ||||
|           case InsProp[p.opcode].Ch[opCount] of | ||||
|             Ch_ROp1: | ||||
|               if p.oper[0]^.typ = top_reg then | ||||
| @ -1901,7 +1901,7 @@ begin | ||||
|                         ptaiprop(tai(p).optinfo)^.CanBeRemoved := True; | ||||
|               else | ||||
|                 begin | ||||
|                   for cnt := 1 to maxch do | ||||
|                   for cnt := 1 to maxinschanges do | ||||
|                     begin | ||||
|                       case InsProp[taicpu(p).opcode].Ch[cnt] of | ||||
|                         Ch_ROp1: | ||||
| @ -2109,7 +2109,14 @@ end. | ||||
| 
 | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.65  2004-09-21 17:25:12  peter | ||||
|   Revision 1.66  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.65  2004/09/21 17:25:12  peter | ||||
|     * paraloc branch merged | ||||
| 
 | ||||
|   Revision 1.64.4.1  2004/09/20 19:28:23  peter | ||||
|  | ||||
| @ -725,7 +725,7 @@ begin | ||||
|               RegReadByInstruction := true; | ||||
|               exit | ||||
|             end; | ||||
|         for opcount := 1 to maxch do | ||||
|         for opcount := 1 to maxinschanges do | ||||
|           case insprop[p.opcode].ch[opcount] of | ||||
|             CH_REAX..CH_REDI,CH_RWEAX..CH_MEDI: | ||||
|               if supreg = tch2reg(insprop[p.opcode].ch[opcount]) then | ||||
| @ -791,7 +791,7 @@ begin | ||||
|          (supreg in [RS_EAX,RS_EDX]) | ||||
|     else | ||||
|       begin | ||||
|         for opcount := 1 to MaxCh do | ||||
|         for opcount := 1 to maxinschanges do | ||||
|           case insprop[p.opcode].Ch[opCount] of | ||||
|             CH_REAX..CH_MEDI: | ||||
|               if tch2reg(InsProp[p.opcode].Ch[opCount]) = supreg then | ||||
| @ -866,7 +866,7 @@ begin | ||||
|         begin | ||||
|           Cnt := 1; | ||||
|           InstrProp := InsProp[taicpu(p1).OpCode]; | ||||
|           while (Cnt <= MaxCh) and | ||||
|           while (Cnt <= maxinschanges) and | ||||
|                 (InstrProp.Ch[Cnt] <> Ch_None) and | ||||
|                 not(TmpResult) Do | ||||
|             begin | ||||
| @ -901,7 +901,7 @@ begin | ||||
|   case p.typ of | ||||
|     ait_instruction: | ||||
|       begin | ||||
|         for l := 1 to MaxCh do | ||||
|         for l := 1 to maxinschanges do | ||||
|           if InsProp[taicpu(p).opcode].Ch[l] in [Ch_WFlags,Ch_RWFlags,Ch_All] then | ||||
|             exit; | ||||
|       end; | ||||
| @ -920,7 +920,7 @@ begin | ||||
|   case p.typ of | ||||
|     ait_instruction: | ||||
|       begin | ||||
|         for l := 1 to MaxCh do | ||||
|         for l := 1 to maxinschanges do | ||||
|           if InsProp[taicpu(p).opcode].Ch[l] in [Ch_RFlags,Ch_RWFlags,Ch_All] then | ||||
|             exit; | ||||
|       end; | ||||
| @ -2555,7 +2555,7 @@ begin | ||||
|               else | ||||
|                 begin | ||||
|                   Cnt := 1; | ||||
|                   while (Cnt <= MaxCh) and | ||||
|                   while (Cnt <= maxinschanges) and | ||||
|                         (InstrProp.Ch[Cnt] <> Ch_None) Do | ||||
|                     begin | ||||
|                       case InstrProp.Ch[Cnt] Of | ||||
| @ -2719,7 +2719,14 @@ end. | ||||
| 
 | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.69  2004-09-26 17:45:30  peter | ||||
|   Revision 1.70  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.69  2004/09/26 17:45:30  peter | ||||
|     * simple regvar support, not yet finished | ||||
| 
 | ||||
|   Revision 1.68  2004/06/20 08:55:31  florian | ||||
|  | ||||
| @ -28,49 +28,6 @@ unit optbase; | ||||
| 
 | ||||
| interface | ||||
| 
 | ||||
| uses cpuinfo, cpubase; | ||||
| 
 | ||||
| 
 | ||||
| {***************************************************************************** | ||||
|                    Opcode propeties (needed for optimizer) | ||||
| *****************************************************************************} | ||||
| 
 | ||||
| {$ifndef NOOPT} | ||||
| Type | ||||
| {What an instruction can change} | ||||
|   TInsChange = (Ch_None, | ||||
|      {Read from a register} | ||||
|      Ch_REAX, Ch_RECX, Ch_REDX, Ch_REBX, Ch_RESP, Ch_REBP, Ch_RESI, Ch_REDI, | ||||
|      {write from a register} | ||||
|      Ch_WEAX, Ch_WECX, Ch_WEDX, Ch_WEBX, Ch_WESP, Ch_WEBP, Ch_WESI, Ch_WEDI, | ||||
|      {read and write from/to a register} | ||||
|      Ch_RWEAX, Ch_RWECX, Ch_RWEDX, Ch_RWEBX, Ch_RWESP, Ch_RWEBP, Ch_RWESI, Ch_RWEDI, | ||||
|      {modify the contents of a register with the purpose of using | ||||
|       this changed content afterwards (add/sub/..., but e.g. not rep | ||||
|       or movsd)} | ||||
|      Ch_MEAX, Ch_MECX, Ch_MEDX, Ch_MEBX, Ch_MESP, Ch_MEBP, Ch_MESI, Ch_MEDI, | ||||
|      Ch_CDirFlag {clear direction flag}, Ch_SDirFlag {set dir flag}, | ||||
|      Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU, | ||||
|      Ch_Rop1, Ch_Wop1, Ch_RWop1,Ch_Mop1, | ||||
|      Ch_Rop2, Ch_Wop2, Ch_RWop2,Ch_Mop2, | ||||
|      Ch_Rop3, Ch_WOp3, Ch_RWOp3,Ch_Mop3, | ||||
|      Ch_WMemEDI, | ||||
|      Ch_All | ||||
|   ); | ||||
| 
 | ||||
| 
 | ||||
| const | ||||
|   MaxCh = 3; { Max things a instruction can change } | ||||
| type | ||||
|   TInsProp = packed record | ||||
|     Ch : Array[1..MaxCh] of TInsChange; | ||||
|   end; | ||||
| 
 | ||||
| const | ||||
|   InsProp : array[tasmop] of TInsProp = | ||||
| {$i i386prop.inc} | ||||
| 
 | ||||
| {$endif NOOPT} | ||||
| 
 | ||||
| implementation | ||||
| 
 | ||||
| @ -79,7 +36,14 @@ end. | ||||
| 
 | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.3  2004-06-20 08:55:31  florian | ||||
|   Revision 1.4  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.3  2004/06/20 08:55:31  florian | ||||
|     * logs truncated | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -135,8 +135,6 @@ unit rgobj; | ||||
|       trgobj=class | ||||
|         preserved_by_proc : tcpuregisterset; | ||||
|         used_in_proc : tcpuregisterset; | ||||
| //        is_reg_var : Tsuperregisterset; {old regvars} | ||||
| //        reg_var_loaded:Tsuperregisterset; {old regvars} | ||||
| 
 | ||||
|         constructor create(Aregtype:Tregistertype; | ||||
|                            Adefaultsub:Tsubregister; | ||||
| @ -170,25 +168,12 @@ unit rgobj; | ||||
|         live_registers:Tsuperregisterworklist; | ||||
|         { can be overriden to add cpu specific interferences } | ||||
|         procedure add_cpu_interferences(p : tai);virtual; | ||||
|         function  get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai; | ||||
|         procedure forward_allocation(pfrom,pto:Tai); | ||||
|         procedure add_constraints(reg:Tregister);virtual; | ||||
|         procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister); | ||||
|         procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister); | ||||
|         procedure add_constraints(reg:Tregister);virtual; | ||||
| 
 | ||||
|         function get_spill_subreg(r : tregister) : tsubregister;virtual; | ||||
|         procedure do_spill_read(list:Taasmoutput;instr:Taicpu; | ||||
|                                 pos:Tai;regidx:word; | ||||
|                                 const spilltemplist:Tspill_temp_list; | ||||
|                                 const regs:Tspillregsinfo);virtual; | ||||
|         procedure do_spill_written(list:Taasmoutput;instr:Taicpu; | ||||
|                                    pos:Tai;regidx:word; | ||||
|                                    const spilltemplist:Tspill_temp_list; | ||||
|                                    const regs:Tspillregsinfo);virtual; | ||||
|         procedure do_spill_readwritten(list:Taasmoutput;instr:Taicpu; | ||||
|                                        pos:Tai;regidx:word; | ||||
|                                        const spilltemplist:Tspill_temp_list; | ||||
|                                        const regs:Tspillregsinfo);virtual; | ||||
|         procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual; | ||||
|         procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual; | ||||
| 
 | ||||
|         function instr_spill_register(list:Taasmoutput; | ||||
|                                       instr:taicpu; | ||||
| @ -603,22 +588,12 @@ unit rgobj; | ||||
|     procedure trgobj.add_edges_used(u:Tsuperregister); | ||||
| 
 | ||||
|     var i:word; | ||||
|         v:tsuperregister; | ||||
| 
 | ||||
|     begin | ||||
|       with live_registers do | ||||
|         if length>0 then | ||||
|           for i:=0 to length-1 do | ||||
|             begin | ||||
|               v:=buf^[i]; | ||||
|               add_edge(u,v); | ||||
|               { add also conflicts with all coalesced registers } | ||||
|               while ri_coalesced in reginfo[v].flags do | ||||
|                 begin | ||||
|                   v:=reginfo[v].alias; | ||||
|                   add_edge(u,v); | ||||
|                 end; | ||||
|             end; | ||||
|             add_edge(u,get_alias(buf^[i])); | ||||
|     end; | ||||
| 
 | ||||
| {$ifdef EXTDEBUG} | ||||
| @ -1638,69 +1613,6 @@ unit rgobj; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function trgobj.get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai; | ||||
|       var | ||||
|         back   : Tsuperregisterworklist; | ||||
|         supreg : tsuperregister; | ||||
|       begin | ||||
|         back.copyfrom(live_registers); | ||||
|         result:=p; | ||||
|         while (p<>nil) and (p.typ=ait_regalloc) do | ||||
|           begin | ||||
|             supreg:=getsupreg(Tai_regalloc(p).reg); | ||||
|             {Rewind the register allocation.} | ||||
|             if (Tai_regalloc(p).ratype=ra_alloc) then | ||||
|               live_registers.delete(supreg) | ||||
|             else | ||||
|               begin | ||||
|                 live_registers.add(supreg); | ||||
|                 if supreg=huntfor1 then | ||||
|                   begin | ||||
|                     get_insert_pos:=Tai(p.previous); | ||||
|                     back.done; | ||||
|                     back.copyfrom(live_registers); | ||||
|                   end; | ||||
|                 if supreg=huntfor2 then | ||||
|                   begin | ||||
|                     get_insert_pos:=Tai(p.previous); | ||||
|                     back.done; | ||||
|                     back.copyfrom(live_registers); | ||||
|                   end; | ||||
|                 if supreg=huntfor3 then | ||||
|                   begin | ||||
|                     get_insert_pos:=Tai(p.previous); | ||||
|                     back.done; | ||||
|                     back.copyfrom(live_registers); | ||||
|                   end; | ||||
|               end; | ||||
|             p:=Tai(p.previous); | ||||
|           end; | ||||
|         live_registers.done; | ||||
|         live_registers:=back; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgobj.forward_allocation(pfrom,pto:Tai); | ||||
|       var | ||||
|         p : tai; | ||||
|       begin | ||||
|         {Forward the register allocation again.} | ||||
|         p:=pfrom; | ||||
|         while (p<>pto) do | ||||
|           begin | ||||
|             if p.typ<>ait_regalloc then | ||||
|               internalerror(200305311); | ||||
|             case Tai_regalloc(p).ratype of | ||||
|               ra_alloc : | ||||
|                 live_registers.add(getsupreg(Tai_regalloc(p).reg)); | ||||
|               ra_dealloc : | ||||
|                 live_registers.delete(getsupreg(Tai_regalloc(p).reg)); | ||||
|             end; | ||||
|             p:=Tai(p.next); | ||||
|           end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean; | ||||
|     { Returns true if any help registers have been used } | ||||
|       var | ||||
| @ -1790,65 +1702,22 @@ unit rgobj; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu; | ||||
|                                    pos:Tai;regidx:word; | ||||
|                                    const spilltemplist:Tspill_temp_list; | ||||
|                                    const regs:Tspillregsinfo); | ||||
| 
 | ||||
|     var helpins:Tai; | ||||
| 
 | ||||
|     begin | ||||
|       with regs[regidx] do | ||||
|         begin | ||||
|           helpins:=spilling_create_load(spilltemplist[orgreg],tempreg); | ||||
|           if pos=nil then | ||||
|             list.insertafter(helpins,list.first) | ||||
|           else | ||||
|             list.insertafter(helpins,pos.next); | ||||
|           ungetregisterinline(list,instr,tempreg); | ||||
|           forward_allocation(tai(helpins.next),instr); | ||||
|         end; | ||||
|     end; | ||||
|     procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); | ||||
|       var | ||||
|         helpins : Tai; | ||||
|       begin | ||||
|         helpins:=spilling_create_load(spilltemp,tempreg); | ||||
|         list.insertbefore(helpins,instr); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu; | ||||
|                                       pos:Tai;regidx:word; | ||||
|                                       const spilltemplist:Tspill_temp_list; | ||||
|                                       const regs:Tspillregsinfo); | ||||
| 
 | ||||
|     var helpins:Tai; | ||||
| 
 | ||||
|     begin | ||||
|       with regs[regidx] do | ||||
|         begin | ||||
|           helpins:=spilling_create_store(tempreg,spilltemplist[orgreg]); | ||||
|           list.insertafter(helpins,instr); | ||||
|           ungetregisterinline(list,helpins,tempreg); | ||||
|         end; | ||||
|     end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure Trgobj.do_spill_readwritten(list:Taasmoutput;instr:taicpu; | ||||
|                                           pos:Tai;regidx:word; | ||||
|                                           const spilltemplist:Tspill_temp_list; | ||||
|                                           const regs:Tspillregsinfo); | ||||
| 
 | ||||
|     var helpins1,helpins2:Tai; | ||||
| 
 | ||||
|     begin | ||||
|       with regs[regidx] do | ||||
|         begin | ||||
|           helpins1:=spilling_create_load(spilltemplist[orgreg],tempreg); | ||||
|           if pos=nil then | ||||
|             list.insertafter(helpins1,list.first) | ||||
|           else | ||||
|             list.insertafter(helpins1,pos.next); | ||||
|           helpins2:=spilling_create_store(tempreg,spilltemplist[orgreg]); | ||||
|           list.insertafter(helpins2,instr); | ||||
|           ungetregisterinline(list,helpins2,tempreg); | ||||
|           forward_allocation(tai(helpins1.next),instr); | ||||
|         end; | ||||
|     end; | ||||
|     procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); | ||||
|       var | ||||
|         helpins : Tai; | ||||
|       begin | ||||
|         helpins:=spilling_create_store(tempreg,spilltemp); | ||||
|         list.insertafter(helpins,instr); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function trgobj.get_spill_subreg(r : tregister) : tsubregister; | ||||
| @ -1863,7 +1732,6 @@ unit rgobj; | ||||
|                                          const spilltemplist:Tspill_temp_list): boolean; | ||||
|       var | ||||
|         counter, regindex: longint; | ||||
|         pos: tai; | ||||
|         regs: tspillregsinfo; | ||||
|         spilled: boolean; | ||||
| 
 | ||||
| @ -1874,7 +1742,7 @@ unit rgobj; | ||||
|         begin | ||||
|           tmpindex := regindex; | ||||
|           supreg:=getsupreg(reg); | ||||
|           // did we already encounter this register? | ||||
|           { did we already encounter this register? } | ||||
|           for i := 0 to pred(regindex) do | ||||
|             if (regs[i].orgreg = supreg) then | ||||
|               begin | ||||
| @ -1887,7 +1755,7 @@ unit rgobj; | ||||
|           regs[tmpindex].spillreg:=reg; | ||||
|           if supregset_in(r,supreg) then | ||||
|             begin | ||||
|               // add/update info on this register | ||||
|               { add/update info on this register } | ||||
|               regs[tmpindex].mustbespilled := true; | ||||
|               case operation of | ||||
|                 operand_read: | ||||
| @ -1916,12 +1784,15 @@ unit rgobj; | ||||
|             if (regs[i].mustbespilled) and | ||||
|                (regs[i].orgreg=supreg) then | ||||
|               begin | ||||
|                 reg:=regs[i].tempreg; | ||||
|                 { Only replace supreg } | ||||
|                 setsupreg(reg,getsupreg(regs[i].tempreg)); | ||||
|                 break; | ||||
|               end; | ||||
|         end; | ||||
| 
 | ||||
| 
 | ||||
|       var | ||||
|         counter2 : longint; | ||||
|         oldlive_registers : tsuperregisterworklist; | ||||
|       begin | ||||
|         result := false; | ||||
|         fillchar(regs,sizeof(regs),0); | ||||
| @ -1966,6 +1837,14 @@ unit rgobj; | ||||
|         if not spilled then | ||||
|           exit; | ||||
| 
 | ||||
|         { Add conflicts with all non-spilled registers } | ||||
|         oldlive_registers.copyfrom(live_registers); | ||||
|         for counter2 := 0 to pred(regindex) do | ||||
|           begin | ||||
|             if (not regs[counter2].mustbespilled) then | ||||
|               live_registers.add(get_alias(regs[counter2].orgreg)); | ||||
|           end; | ||||
| 
 | ||||
|         { generate the spilling code } | ||||
|         result := true; | ||||
|         for counter := 0 to pred(regindex) do | ||||
| @ -1973,18 +1852,27 @@ unit rgobj; | ||||
|             begin | ||||
|               if mustbespilled then | ||||
|                 begin | ||||
|                   pos:=get_insert_pos(Tai(instr.previous),regs[0].orgreg,regs[1].orgreg,regs[2].orgreg); | ||||
|                   getregisterinline(list,pos,get_spill_subreg(regs[counter].spillreg),tempreg); | ||||
|                   getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg); | ||||
| 
 | ||||
|                   if regread then | ||||
|                     if regwritten then | ||||
|                       do_spill_readwritten(list,instr,pos,counter,spilltemplist,regs) | ||||
|                     else | ||||
|                       do_spill_read(list,instr,pos,counter,spilltemplist,regs) | ||||
|                   else | ||||
|                     do_spill_written(list,instr,pos,counter,spilltemplist,regs) | ||||
|                     do_spill_read(list,instr,spilltemplist[orgreg],tempreg); | ||||
|                   if regwritten then | ||||
|                     do_spill_written(list,instr,spilltemplist[orgreg],tempreg); | ||||
|                 end; | ||||
|             end; | ||||
| 
 | ||||
|         { Release temp registers after all registers for the instruction are spilled } | ||||
|         for counter := 0 to pred(regindex) do | ||||
|           with regs[counter] do | ||||
|             begin | ||||
|               if mustbespilled then | ||||
|                 ungetregisterinline(list,instr,tempreg); | ||||
|             end; | ||||
| 
 | ||||
|         { restore live registers } | ||||
|         live_registers.done; | ||||
|         live_registers:=oldlive_registers; | ||||
| 
 | ||||
|         { substitute registers } | ||||
|         for counter:=0 to instr.ops-1 do | ||||
|          with instr.oper[counter]^ do | ||||
| @ -2015,7 +1903,14 @@ unit rgobj; | ||||
| end. | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.137  2004-09-26 17:45:30  peter | ||||
|   Revision 1.138  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.137  2004/09/26 17:45:30  peter | ||||
|     * simple regvar support, not yet finished | ||||
| 
 | ||||
|   Revision 1.136  2004/09/25 14:23:54  peter | ||||
|  | ||||
| @ -36,12 +36,8 @@ unit rgcpu; | ||||
|       trgcpu=class(trgobj) | ||||
|         procedure add_constraints(reg:tregister);override; | ||||
|         function get_spill_subreg(r : tregister) : tsubregister;override; | ||||
|         procedure do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                 const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
|         procedure do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                    const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
|         procedure do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                        const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
|         procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override; | ||||
|         procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
| @ -91,159 +87,89 @@ implementation | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgcpu.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                    const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|     procedure trgcpu.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); | ||||
|       var | ||||
|         helpins: tai; | ||||
|         tmpref,ref : treference; | ||||
|         helpins  : tai; | ||||
|         tmpref   : treference; | ||||
|         helplist : taasmoutput; | ||||
|         tmpreg : tregister; | ||||
|         hreg     : tregister; | ||||
|       begin | ||||
|         ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|         if abs(spilltemp.offset)>4095 then | ||||
|           begin | ||||
|             helplist:=taasmoutput.create; | ||||
|             reference_reset(tmpref); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               getregisterinline(helplist,nil,defaultsub,tmpreg) | ||||
|             if getregtype(tempreg)=R_INTREGISTER then | ||||
|               hreg:=tempreg | ||||
|             else | ||||
|               tmpreg:=cg.getintregister(helplist,OS_ADDR); | ||||
|               hreg:=cg.getintregister(helplist,OS_ADDR); | ||||
| 
 | ||||
|             tmpref.offset:=ref.offset; | ||||
|             reference_reset(tmpref); | ||||
|             tmpref.offset:=spilltemp.offset; | ||||
|             tmpref.refaddr:=addr_hi; | ||||
|             helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg)); | ||||
|             helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg)); | ||||
| 
 | ||||
|             tmpref.refaddr:=addr_lo; | ||||
|             helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg)); | ||||
|             helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg)); | ||||
| 
 | ||||
|             if ref.index<>NR_NO then | ||||
|               internalerror(200401263); | ||||
|             ref.index:=tmpreg; | ||||
|             ref.offset:=0; | ||||
|             reference_reset_base(tmpref,hreg,0); | ||||
| 
 | ||||
|             helpins:=spilling_create_load(ref,regs[regidx].tempreg); | ||||
|             helpins:=spilling_create_load(spilltemp,tempreg); | ||||
|             helplist.concat(helpins); | ||||
|             if pos=nil then | ||||
|               list.insertlistafter(list.first,helplist) | ||||
|             else | ||||
|               list.insertlistafter(pos.next,helplist); | ||||
|             helplist.free; | ||||
| 
 | ||||
|             ungetregisterinline(list,helpins,regs[regidx].tempreg); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               ungetregisterinline(list,helpins,tmpreg); | ||||
| 
 | ||||
|             forward_allocation(tai(helpins.next),instr); | ||||
|             list.insertlistbefore(instr,helplist) | ||||
|           end | ||||
|         else | ||||
|           inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs); | ||||
|           inherited do_spill_read(list,instr,spilltemp,tempreg); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgcpu.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                       const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|     procedure trgcpu.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); | ||||
|       var | ||||
|         helpins: tai; | ||||
|         ref,tmpref : treference; | ||||
|         helpins  : tai; | ||||
|         tmpref   : treference; | ||||
|         helplist : taasmoutput; | ||||
|         tmpreg : tregister; | ||||
|         hreg     : tregister; | ||||
|       begin | ||||
|         ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|         if abs(spilltemp.offset)>4095 then | ||||
|           begin | ||||
|             helplist:=taasmoutput.create; | ||||
|             reference_reset(tmpref); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               getregisterinline(helplist,pos,defaultsub,tmpreg) | ||||
|             if getregtype(tempreg)=R_INTREGISTER then | ||||
|               getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg) | ||||
|             else | ||||
|               tmpreg:=cg.getintregister(helplist,OS_ADDR); | ||||
|               hreg:=cg.getintregister(helplist,OS_ADDR); | ||||
| 
 | ||||
|             tmpref.offset:=ref.offset; | ||||
|             reference_reset(tmpref); | ||||
|             tmpref.offset:=spilltemp.offset; | ||||
|             tmpref.refaddr:=addr_hi; | ||||
|             helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg)); | ||||
|             helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg)); | ||||
| 
 | ||||
|             tmpref.refaddr:=addr_lo; | ||||
|             helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg)); | ||||
|             helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg)); | ||||
| 
 | ||||
|             if ref.index<>NR_NO then | ||||
|               internalerror(200401263); | ||||
|             ref.index:=tmpreg; | ||||
|             ref.offset:=0; | ||||
|             reference_reset_base(tmpref,hreg,0); | ||||
| 
 | ||||
|             helpins:=spilling_create_store(regs[regidx].tempreg,ref); | ||||
|             helpins:=spilling_create_store(tempreg,spilltemp); | ||||
|             helplist.concat(helpins); | ||||
|             list.insertlistafter(instr,helplist); | ||||
|             helplist.free; | ||||
|             if getregtype(tempreg)=R_INTREGISTER then | ||||
|               ungetregisterinline(helplist,tai(helplist.last),hreg); | ||||
| 
 | ||||
|             ungetregisterinline(list,helpins,regs[regidx].tempreg); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               ungetregisterinline(list,helpins,tmpreg); | ||||
|             list.insertlistafter(instr,helplist) | ||||
|           end | ||||
|         else | ||||
|           inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgcpu.do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                           const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|       var | ||||
|         helpins1, helpins2: tai; | ||||
|         tmpref,ref : treference; | ||||
|         helplist : taasmoutput; | ||||
|          tmpreg : tregister; | ||||
|       begin | ||||
|         ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|           begin | ||||
|             helplist:=taasmoutput.create; | ||||
|             reference_reset(tmpref); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               getregisterinline(helplist,nil,defaultsub,tmpreg) | ||||
|             else | ||||
|               tmpreg:=cg.getintregister(helplist,OS_ADDR); | ||||
| 
 | ||||
|             tmpref.offset:=ref.offset; | ||||
|             tmpref.refaddr:=addr_hi; | ||||
|             helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg)); | ||||
| 
 | ||||
|             tmpref.refaddr:=addr_lo; | ||||
|             helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg)); | ||||
| 
 | ||||
|             if ref.index<>NR_NO then | ||||
|               internalerror(200401263); | ||||
|             ref.index:=tmpreg; | ||||
|             ref.offset:=0; | ||||
| 
 | ||||
|             helpins1:=spilling_create_load(ref,regs[regidx].tempreg); | ||||
|             helplist.concat(helpins1); | ||||
|             if pos=nil then | ||||
|               list.insertlistafter(list.first,helplist) | ||||
|             else | ||||
|               list.insertlistafter(pos.next,helplist); | ||||
|             helplist.free; | ||||
| 
 | ||||
|             helpins2:=spilling_create_store(regs[regidx].tempreg,ref); | ||||
|             list.insertafter(helpins2,instr); | ||||
|             ungetregisterinline(list,helpins2,regs[regidx].tempreg); | ||||
| 
 | ||||
|             if getregtype(regs[regidx].tempreg)=R_INTREGISTER then | ||||
|               ungetregisterinline(list,helpins2,tmpreg); | ||||
| 
 | ||||
|             forward_allocation(tai(helpins1.next),instr); | ||||
|           end | ||||
|         else | ||||
|           inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs); | ||||
|       end; | ||||
|           inherited do_spill_written(list,instr,spilltemp,tempreg); | ||||
|     end; | ||||
| 
 | ||||
| end. | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.27  2004-10-01 17:33:47  peter | ||||
|   Revision 1.28  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.27  2004/10/01 17:33:47  peter | ||||
|     * indents | ||||
| 
 | ||||
|   Revision 1.26  2004/09/28 20:19:36  peter | ||||
|  | ||||
| @ -130,6 +130,36 @@ interface | ||||
|       instabentries = {$i i386nop.inc} | ||||
| {$endif x86_64} | ||||
|       maxinfolen    = 8; | ||||
|       MaxInsChanges = 3; { Max things a instruction can change } | ||||
| 
 | ||||
|     type | ||||
|       { What an instruction can change. Needed for optimizer and spilling code } | ||||
|       TInsChange = (Ch_None, | ||||
|         {Read from a register} | ||||
|         Ch_REAX, Ch_RECX, Ch_REDX, Ch_REBX, Ch_RESP, Ch_REBP, Ch_RESI, Ch_REDI, | ||||
|         {write from a register} | ||||
|         Ch_WEAX, Ch_WECX, Ch_WEDX, Ch_WEBX, Ch_WESP, Ch_WEBP, Ch_WESI, Ch_WEDI, | ||||
|         {read and write from/to a register} | ||||
|         Ch_RWEAX, Ch_RWECX, Ch_RWEDX, Ch_RWEBX, Ch_RWESP, Ch_RWEBP, Ch_RWESI, Ch_RWEDI, | ||||
|         {modify the contents of a register with the purpose of using | ||||
|          this changed content afterwards (add/sub/..., but e.g. not rep | ||||
|          or movsd)} | ||||
|         Ch_MEAX, Ch_MECX, Ch_MEDX, Ch_MEBX, Ch_MESP, Ch_MEBP, Ch_MESI, Ch_MEDI, | ||||
|         Ch_CDirFlag {clear direction flag}, Ch_SDirFlag {set dir flag}, | ||||
|         Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU, | ||||
|         Ch_Rop1, Ch_Wop1, Ch_RWop1,Ch_Mop1, | ||||
|         Ch_Rop2, Ch_Wop2, Ch_RWop2,Ch_Mop2, | ||||
|         Ch_Rop3, Ch_WOp3, Ch_RWOp3,Ch_Mop3, | ||||
|         Ch_WMemEDI, | ||||
|         Ch_All | ||||
|       ); | ||||
| 
 | ||||
|       TInsProp = packed record | ||||
|         Ch : Array[1..MaxInsChanges] of TInsChange; | ||||
|       end; | ||||
| 
 | ||||
|     const | ||||
|       InsProp : array[tasmop] of TInsProp = {$i i386prop.inc} | ||||
| 
 | ||||
|     type | ||||
|       TOperandOrder = (op_intel,op_att); | ||||
| @ -201,6 +231,8 @@ interface | ||||
|          procedure Pass2(objdata:TAsmObjectdata);virtual; | ||||
|          procedure SetOperandOrder(order:TOperandOrder); | ||||
|          function is_same_reg_move(regtype: Tregistertype):boolean;override; | ||||
|          { register spilling code } | ||||
|          function spilling_get_operation_type(opnr: longint): topertype;override; | ||||
|       protected | ||||
|          procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override; | ||||
|          procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override; | ||||
| @ -366,6 +398,12 @@ implementation | ||||
|       ); | ||||
| {$endif x86_64} | ||||
| 
 | ||||
|     { Operation type for spilling code } | ||||
|     type | ||||
|       toperation_type_table=array[tasmop,0..Max_Operands] of topertype; | ||||
|     var | ||||
|       operation_type_table : ^toperation_type_table; | ||||
| 
 | ||||
| 
 | ||||
| {**************************************************************************** | ||||
|                               TAI_ALIGN | ||||
| @ -1932,15 +1970,74 @@ implementation | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure build_spilling_operation_type_table; | ||||
|       var | ||||
|         opcode : tasmop; | ||||
|         i      : integer; | ||||
|       begin | ||||
|         new(operation_type_table); | ||||
|         fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read)); | ||||
|         for opcode:=low(tasmop) to high(tasmop) do | ||||
|           begin | ||||
|             for i:=1 to MaxInsChanges do | ||||
|               begin | ||||
|                 case InsProp[opcode].Ch[i] of | ||||
|                   Ch_Rop1 : | ||||
|                     operation_type_table^[opcode,0]:=operand_read; | ||||
|                   Ch_Wop1 : | ||||
|                     operation_type_table^[opcode,0]:=operand_write; | ||||
|                   Ch_RWop1, | ||||
|                   Ch_Mop1 : | ||||
|                     operation_type_table^[opcode,0]:=operand_readwrite; | ||||
|                   Ch_Rop2 : | ||||
|                     operation_type_table^[opcode,1]:=operand_read; | ||||
|                   Ch_Wop2 : | ||||
|                     operation_type_table^[opcode,1]:=operand_write; | ||||
|                   Ch_RWop2, | ||||
|                   Ch_Mop2 : | ||||
|                     operation_type_table^[opcode,1]:=operand_readwrite; | ||||
|                   Ch_Rop3 : | ||||
|                     operation_type_table^[opcode,2]:=operand_read; | ||||
|                   Ch_Wop3 : | ||||
|                     operation_type_table^[opcode,2]:=operand_write; | ||||
|                   Ch_RWop3, | ||||
|                   Ch_Mop3 : | ||||
|                     operation_type_table^[opcode,2]:=operand_readwrite; | ||||
|                 end; | ||||
|               end; | ||||
|           end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function taicpu.spilling_get_operation_type(opnr: longint): topertype; | ||||
|       begin | ||||
|         result:=operation_type_table^[opcode,opnr]; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function spilling_create_load(const ref:treference;r:tregister): tai; | ||||
|       begin | ||||
|         internalerror(200406131); | ||||
|         case getregtype(r) of | ||||
|           R_INTREGISTER : | ||||
|             result:=taicpu.op_ref_reg(A_MOV,reg2opsize(r),ref,r); | ||||
|           R_MMREGISTER : | ||||
|             result:=taicpu.op_ref_reg(A_MOVSD,reg2opsize(r),ref,r); | ||||
|           else | ||||
|             internalerror(200401041); | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     function spilling_create_store(r:tregister; const ref:treference): tai; | ||||
|       begin | ||||
|         internalerror(200406132); | ||||
|         case getregtype(r) of | ||||
|           R_INTREGISTER : | ||||
|             result:=taicpu.op_reg_ref(A_MOV,reg2opsize(r),r,ref); | ||||
|           R_MMREGISTER : | ||||
|             result:=taicpu.op_reg_ref(A_MOVSD,reg2opsize(r),r,ref); | ||||
|           else | ||||
|             internalerror(200401041); | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
| @ -1970,6 +2067,7 @@ implementation | ||||
| 
 | ||||
|     procedure InitAsm; | ||||
|       begin | ||||
|         build_spilling_operation_type_table; | ||||
| {$ifndef NOAG386BIN} | ||||
|         if not assigned(instabcache) then | ||||
|           BuildInsTabCache; | ||||
| @ -1979,12 +2077,17 @@ implementation | ||||
| 
 | ||||
|     procedure DoneAsm; | ||||
|       begin | ||||
|         if assigned(operation_type_table) then | ||||
|           begin | ||||
|             dispose(operation_type_table); | ||||
|             operation_type_table:=nil; | ||||
|           end; | ||||
| {$ifndef NOAG386BIN} | ||||
|         if assigned(instabcache) then | ||||
|         begin | ||||
|           dispose(instabcache); | ||||
|           instabcache:=nil; | ||||
|         end; | ||||
|           begin | ||||
|             dispose(instabcache); | ||||
|             instabcache:=nil; | ||||
|           end; | ||||
| {$endif NOAG386BIN} | ||||
|       end; | ||||
| 
 | ||||
| @ -1995,7 +2098,14 @@ begin | ||||
| end. | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.58  2004-09-27 15:12:47  peter | ||||
|   Revision 1.59  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.58  2004/09/27 15:12:47  peter | ||||
|     * IE when expecting top_ref | ||||
| 
 | ||||
|   Revision 1.57  2004/06/20 08:55:32  florian | ||||
|  | ||||
| @ -551,11 +551,14 @@ unit cgx86; | ||||
|         if s in [S_BL,S_WL,S_L] then | ||||
|           reg2:=makeregsize(list,reg2,OS_32); | ||||
| {$endif x86_64} | ||||
|         instr:=taicpu.op_reg_reg(op,s,reg1,reg2); | ||||
|         { Notify the register allocator that we have written a move instruction so | ||||
|           it can try to eliminate it. } | ||||
|         add_move_instruction(instr); | ||||
|         list.concat(instr); | ||||
|         if (reg1<>reg2) then | ||||
|           begin | ||||
|             instr:=taicpu.op_reg_reg(op,s,reg1,reg2); | ||||
|             { Notify the register allocator that we have written a move instruction so | ||||
|               it can try to eliminate it. } | ||||
|             add_move_instruction(instr); | ||||
|             list.concat(instr); | ||||
|           end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
| @ -1672,7 +1675,14 @@ unit cgx86; | ||||
| end. | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.126  2004-10-03 12:42:22  florian | ||||
|   Revision 1.127  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.126  2004/10/03 12:42:22  florian | ||||
|     * made sqrt, sqr and abs internal for the sparc | ||||
| 
 | ||||
|   Revision 1.125  2004/09/25 14:23:55  peter | ||||
|  | ||||
| @ -36,10 +36,21 @@ unit rgx86; | ||||
| 
 | ||||
|     type | ||||
|        trgx86 = class(trgobj) | ||||
| {$ifdef OLDRGX86} | ||||
|          function instr_spill_register(list:Taasmoutput; | ||||
|                                        instr:taicpu; | ||||
|                                        const r:Tsuperregisterset; | ||||
|                                        const spilltemplist:Tspill_temp_list): boolean;override; | ||||
| {$endif OLDRGX86} | ||||
|         function  get_spill_subreg(r : tregister) : tsubregister;override; | ||||
| { | ||||
|         procedure do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                 const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
|         procedure do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                    const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
|         procedure do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                        const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override; | ||||
| } | ||||
|        end; | ||||
| 
 | ||||
|        tpushedsavedloc = record | ||||
| @ -107,6 +118,7 @@ implementation | ||||
|                                     Trgcpu | ||||
| ******************************************************************************} | ||||
| 
 | ||||
| {$ifdef OLDRGX86} | ||||
|     function trgx86.instr_spill_register(list:Taasmoutput; | ||||
|                                          instr:taicpu; | ||||
|                                          const r:Tsuperregisterset; | ||||
| @ -485,8 +497,67 @@ implementation | ||||
|          end; | ||||
|        end; | ||||
|     end; | ||||
| {$endif OLDRGX86} | ||||
| 
 | ||||
| 
 | ||||
|     function trgx86.get_spill_subreg(r : tregister) : tsubregister; | ||||
|       begin | ||||
|         result:=getsubreg(r); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|       (* | ||||
|     procedure trgx86.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                    const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|       var | ||||
|         helpins: tai; | ||||
|         tmpref,ref : treference; | ||||
|         helplist : taasmoutput; | ||||
|         tmpreg : tregister; | ||||
|       begin | ||||
| {        ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|           begin | ||||
|           end | ||||
|         else } | ||||
|           inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgx86.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                       const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|       var | ||||
|         helpins: tai; | ||||
|         ref,tmpref : treference; | ||||
|         helplist : taasmoutput; | ||||
|         tmpreg : tregister; | ||||
|       begin | ||||
| {        ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|           begin | ||||
|           end | ||||
|         else } | ||||
|           inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure trgx86.do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word; | ||||
|                                           const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo); | ||||
|       var | ||||
|         helpins1, helpins2: tai; | ||||
|         tmpref,ref : treference; | ||||
|         helplist : taasmoutput; | ||||
|          tmpreg : tregister; | ||||
|       begin | ||||
| {        ref:=spilltemplist[regs[regidx].orgreg]; | ||||
|         if abs(ref.offset)>4095 then | ||||
|           begin | ||||
|           end | ||||
|         else  } | ||||
|           inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs); | ||||
|       end; | ||||
| *) | ||||
| 
 | ||||
| {****************************************************************************** | ||||
|                                   Trgx86fpu | ||||
| ******************************************************************************} | ||||
| @ -619,7 +690,14 @@ implementation | ||||
| end. | ||||
| { | ||||
|   $Log$ | ||||
|   Revision 1.6  2004-09-27 14:49:45  peter | ||||
|   Revision 1.7  2004-10-04 20:46:22  peter | ||||
|     * spilling code rewritten for x86. It now used the generic | ||||
|       spilling routines. Special x86 optimization still needs | ||||
|       to be added. | ||||
|     * Spilling fixed when both operands needed to be spilled | ||||
|     * Cleanup of spilling routine, do_spill_readwritten removed | ||||
| 
 | ||||
|   Revision 1.6  2004/09/27 14:49:45  peter | ||||
|     * handle 3 operand opcodes the same as 2 operand opcodes, the | ||||
|       third operand can only be a const or register CL, so it doesn't | ||||
|       affect spilling | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 peter
						peter