diff --git a/compiler/cg64f32.pas b/compiler/cg64f32.pas index e226cbaccf..2c0feefa93 100644 --- a/compiler/cg64f32.pas +++ b/compiler/cg64f32.pas @@ -164,7 +164,7 @@ unit cg64f32; begin tmpreg := cg.get_scratch_reg_int(list); got_scratch:=true; - cg.a_load_reg_reg(list,OS_ADDR,tmpref.base,tmpreg); + cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg); tmpref.base:=tmpreg; end else @@ -175,7 +175,7 @@ unit cg64f32; begin tmpreg:=cg.get_scratch_reg_int(list); got_scratch:=true; - cg.a_load_reg_reg(list,OS_ADDR,tmpref.index,tmpreg); + cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.index,tmpreg); tmpref.index:=tmpreg; end; cg.a_load_ref_reg(list,OS_32,tmpref,reg.reglo); @@ -189,8 +189,8 @@ unit cg64f32; procedure tcg64f32.a_load64_reg_reg(list : taasmoutput;regsrc,regdst : tregister64); begin - cg.a_load_reg_reg(list,OS_32,regsrc.reglo,regdst.reglo); - cg.a_load_reg_reg(list,OS_32,regsrc.reghi,regdst.reghi); + cg.a_load_reg_reg(list,OS_32,OS_32,regsrc.reglo,regdst.reglo); + cg.a_load_reg_reg(list,OS_32,OS_32,regsrc.reghi,regdst.reghi); end; procedure tcg64f32.a_load64_const_reg(list : taasmoutput;value : qword;reg : tregister64); @@ -321,7 +321,7 @@ unit cg64f32; LOC_CREFERENCE : a_load64low_ref_reg(list,l.reference,reg); LOC_REGISTER : - cg.a_load_reg_reg(list,OS_32,l.registerlow,reg); + cg.a_load_reg_reg(list,OS_32,OS_32,l.registerlow,reg); LOC_CONSTANT : cg.a_load_const_reg(list,OS_32,lo(l.valueqword),reg); else @@ -336,7 +336,7 @@ unit cg64f32; LOC_CREFERENCE : a_load64high_ref_reg(list,l.reference,reg); LOC_REGISTER : - cg.a_load_reg_reg(list,OS_32,l.registerhigh,reg); + cg.a_load_reg_reg(list,OS_32,OS_32,l.registerhigh,reg); LOC_CONSTANT : cg.a_load_const_reg(list,OS_32,hi(l.valueqword),reg); else @@ -738,7 +738,12 @@ begin end. { $Log$ - Revision 1.29 2002-09-10 21:24:38 jonas + Revision 1.30 2002-09-17 18:54:01 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.29 2002/09/10 21:24:38 jonas * fixed a_param64_ref Revision 1.28 2002/09/07 15:25:00 peter diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index c2aeb28985..4a784c0d65 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -185,7 +185,7 @@ unit cgobj; procedure a_load_const_ref(list : taasmoutput;size : tcgsize;a : aword;const ref : treference);virtual; procedure a_load_const_loc(list : taasmoutput;a : aword;const loc : tlocation); procedure a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);virtual; abstract; - procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);virtual; abstract; + procedure a_load_reg_reg(list : taasmoutput;fromsize, tosize : tcgsize;reg1,reg2 : tregister);virtual; abstract; procedure a_load_reg_loc(list : taasmoutput;size : tcgsize;reg : tregister;const loc: tlocation); procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);virtual; abstract; procedure a_load_ref_ref(list : taasmoutput;size : tcgsize;const sref : treference;const dref : treference);virtual; @@ -573,7 +573,7 @@ unit cgobj; begin case locpara.loc of LOC_REGISTER,LOC_CREGISTER: - a_load_reg_reg(list,size,r,locpara.register); + a_load_reg_reg(list,size,locpara.size,r,locpara.register); LOC_REFERENCE: begin if locpara.sp_fixup<>0 then @@ -732,7 +732,7 @@ unit cgobj; LOC_REFERENCE,LOC_CREFERENCE: a_load_reg_ref(list,size,reg,loc.reference); LOC_REGISTER,LOC_CREGISTER: - a_load_reg_reg(list,size,reg,loc.register); + a_load_reg_reg(list,size,loc.size,reg,loc.register); else internalerror(200203271); end; @@ -746,7 +746,7 @@ unit cgobj; LOC_REFERENCE,LOC_CREFERENCE: a_load_ref_reg(list,loc.size,loc.reference,reg); LOC_REGISTER,LOC_CREGISTER: - a_load_reg_reg(list,loc.size,loc.register,reg); + a_load_reg_reg(list,loc.size,loc.size,loc.register,reg); LOC_CONSTANT: a_load_const_reg(list,loc.size,loc.value,reg); else @@ -975,14 +975,14 @@ unit cgobj; procedure tcg.a_op_const_reg_reg(list: taasmoutput; op: TOpCg; size: tcgsize; a: aword; src, dst: tregister); begin - a_load_reg_reg(list,size,src,dst); + a_load_reg_reg(list,size,size,src,dst); a_op_const_reg(list,op,a,dst); end; procedure tcg.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); begin - a_load_reg_reg(list,size,src2,dst); + a_load_reg_reg(list,size,size,src2,dst); a_op_reg_reg(list,op,size,src1,dst); end; @@ -1413,7 +1413,7 @@ unit cgobj; reference_reset_base(href, procinfo.framepointer,procinfo.selfpointer_offset); a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1)); a_call_name(list,'FPC_NEW_CLASS'); - a_load_reg_reg(list,OS_ADDR,accumulator,SELF_POINTER_REG); + a_load_reg_reg(list,OS_ADDR,OS_ADDR,accumulator,SELF_POINTER_REG); { save the self pointer result } a_load_reg_ref(list,OS_ADDR,SELF_POINTER_REG,href); a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,accumulator,faillabel); @@ -1436,7 +1436,7 @@ unit cgobj; a_param_reg(list, OS_ADDR,hregister,paramanager.getintparaloc(1)); free_scratch_reg(list, hregister); a_call_name(list,'FPC_HELP_CONSTRUCTOR'); - a_load_reg_reg(list,OS_ADDR,accumulator,SELF_POINTER_REG); + a_load_reg_reg(list,OS_ADDR,OS_ADDR,accumulator,SELF_POINTER_REG); a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,accumulator,faillabel); end else @@ -1595,7 +1595,12 @@ finalization end. { $Log$ - Revision 1.58 2002-09-09 19:29:29 peter + Revision 1.59 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.58 2002/09/09 19:29:29 peter * fixed dynarr_decr_ref call Revision 1.57 2002/09/07 15:25:01 peter diff --git a/compiler/i386/n386cal.pas b/compiler/i386/n386cal.pas index 0958cde4df..b112e8f6f0 100644 --- a/compiler/i386/n386cal.pas +++ b/compiler/i386/n386cal.pas @@ -722,7 +722,7 @@ implementation LOC_CREGISTER, LOC_REGISTER: begin - cg.a_load_reg_reg(exprasmlist,OS_ADDR,methodpointer.location.register,R_ESI); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,methodpointer.location.register,R_ESI); rg.ungetregisterint(exprasmlist,methodpointer.location.register); end; else @@ -1145,7 +1145,7 @@ implementation cg.free_scratch_reg(exprasmlist,tmpreg); exprasmList.concat(tai_regalloc.Alloc(accumulator)); cg.a_label(exprasmlist,constructorfailed); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,self_pointer_reg,accumulator); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,self_pointer_reg,accumulator); end; { handle function results } @@ -1211,7 +1211,7 @@ implementation location.register:=rg.getexplicitregisterint(exprasmlist,accumulator); hregister:=rg.makeregsize(accumulator,cgsize); location.register:=rg.makeregsize(location.register,cgsize); - cg.a_load_reg_reg(exprasmlist,cgsize,hregister,location.register); + cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,hregister,location.register); end; end; end; @@ -1225,7 +1225,7 @@ implementation begin location_reset(location,LOC_REGISTER,OS_INT); location.register:=rg.getexplicitregisterint(exprasmlist,accumulator); - cg.a_load_reg_reg(exprasmlist,OS_INT,accumulator,location.register); + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,accumulator,location.register); end; end; end; @@ -1311,7 +1311,12 @@ begin end. { $Log$ - Revision 1.71 2002-09-16 19:07:37 peter + Revision 1.72 2002-09-17 18:54:03 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.71 2002/09/16 19:07:37 peter * push 0 instead of VMT when calling a constructor from a member Revision 1.70 2002/09/07 15:25:10 peter diff --git a/compiler/i386/n386cnv.pas b/compiler/i386/n386cnv.pas index f9514f3a8d..2a67e7609d 100644 --- a/compiler/i386/n386cnv.pas +++ b/compiler/i386/n386cnv.pas @@ -118,7 +118,7 @@ implementation begin hregister:=cg.get_scratch_reg_int(exprasmlist); freereg:=true; - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hregister); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_32,left.location.register,hregister); end; end; end; @@ -256,7 +256,7 @@ implementation if left.location.size in [OS_64,OS_S64] then begin hregister:=cg.get_scratch_reg_int(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_32,left.location.registerlow,hregister); + cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,left.location.registerlow,hregister); cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister); cg.free_scratch_reg(exprasmlist,hregister); end @@ -376,7 +376,12 @@ begin end. { $Log$ - Revision 1.48 2002-08-14 19:19:14 carl + Revision 1.49 2002-09-17 18:54:03 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.48 2002/08/14 19:19:14 carl * first_int_to_real moved to i386 (other one is generic) Revision 1.47 2002/08/11 14:32:30 peter diff --git a/compiler/i386/n386set.pas b/compiler/i386/n386set.pas index 4ce64252c7..52ec11dd8a 100644 --- a/compiler/i386/n386set.pas +++ b/compiler/i386/n386set.pas @@ -225,7 +225,7 @@ implementation if ranges then begin pleftreg:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,pleftreg); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,pleftreg); if opsize <> S_L then emit_const_reg(A_AND,S_L,255,pleftreg); opsize := S_L; @@ -387,7 +387,7 @@ implementation LOC_CREGISTER: begin hr:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hr); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr); end; else begin @@ -456,7 +456,7 @@ implementation LOC_CREGISTER: begin hr:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hr); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr); emit_const_reg(A_CMP,S_L,31,hr); emitjmp(C_NA,l); { reset carry flag } @@ -594,7 +594,7 @@ implementation objectlibrary.getlabel(table); { make it a 32bit register } indexreg:=rg.makeregsize(hregister,OS_INT); - cg.a_load_reg_reg(exprasmlist,opsize,hregister,indexreg); + cg.a_load_reg_reg(exprasmlist,opsize,OS_INT,hregister,indexreg); { create reference } reference_reset_symbol(href,table,0); href.offset:=(-longint(min_))*4; @@ -706,7 +706,12 @@ begin end. { $Log$ - Revision 1.42 2002-09-16 18:08:26 peter + Revision 1.43 2002-09-17 18:54:05 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.42 2002/09/16 18:08:26 peter * fix last optimization in genlinearlist, detected by bug tw1066 * use generic casenode.pass2 routine and override genlinearlist * add jumptable support to generic casenode, by default there is diff --git a/compiler/m68k/cgcpu.pas b/compiler/m68k/cgcpu.pas index b299443feb..7dda1980f9 100644 --- a/compiler/m68k/cgcpu.pas +++ b/compiler/m68k/cgcpu.pas @@ -39,7 +39,7 @@ unit cgcpu; procedure a_call_reg(list : taasmoutput;reg : tregister);override; procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);override; procedure a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);override; - procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);override; + procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override; procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);override; procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);override; procedure a_loadfpu_reg_reg(list: taasmoutput; reg1, reg2: tregister); override; @@ -260,12 +260,12 @@ Implementation list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[size],register,href)); end; - procedure tcg68k.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister); + procedure tcg68k.a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister); begin { move to destination register } list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1,reg2)); { zero/sign extend register to 32-bit } - sign_extend(list, size, reg2); + sign_extend(list, fromsize, reg2); end; procedure tcg68k.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister); @@ -1244,7 +1244,12 @@ end. { $Log$ - Revision 1.8 2002-09-08 15:12:45 carl + Revision 1.9 2002-09-17 18:54:05 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.8 2002/09/08 15:12:45 carl + a_call_reg Revision 1.7 2002/09/07 20:53:28 carl diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 4ab17c8d6c..dd26cb5cd0 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -227,12 +227,17 @@ implementation if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then begin { allow passing nil to a procvardef (methodpointer) } - if (left.nodetype=typeconvn) and +(* if (left.nodetype=typeconvn) and (left.resulttype.def.deftype=procvardef) and (ttypeconvnode(left).left.nodetype=niln) then +*) + if (left.location.size <> OS_NO) then begin tg.GetTemp(exprasmlist,tcgsize2size[left.location.size],tt_normal,href); - cg.a_load_loc_ref(exprasmlist,left.location,href); + if not (left.location.size in [OS_64,OS_S64]) then + cg.a_load_loc_ref(exprasmlist,left.location,href) + else + cg64.a_load64_loc_ref(exprasmlist,left.location,href); location_reset(left.location,LOC_REFERENCE,left.location.size); left.location.reference:=href; end @@ -746,7 +751,7 @@ implementation LOC_CREGISTER, LOC_REGISTER: begin - cg.a_load_reg_reg(exprasmlist,OS_ADDR,methodpointer.location.register,R_ESI); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,methodpointer.location.register,R_ESI); rg.ungetregisterint(exprasmlist,methodpointer.location.register); end; else @@ -1131,7 +1136,7 @@ implementation cg.free_scratch_reg(exprasmlist,tmpreg); exprasmList.concat(tai_regalloc.Alloc(accumulator)); cg.a_label(exprasmlist,constructorfailed); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,self_pointer_reg,accumulator); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,self_pointer_reg,accumulator); end; { handle function results } @@ -1197,7 +1202,7 @@ implementation location.register:=rg.getexplicitregisterint(exprasmlist,resultloc.register); hregister:=rg.makeregsize(resultloc.register,cgsize); location.register:=rg.makeregsize(location.register,cgsize); - cg.a_load_reg_reg(exprasmlist,cgsize,hregister,location.register); + cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,hregister,location.register); end; end; LOC_FPUREGISTER: @@ -1483,7 +1488,12 @@ begin end. { $Log$ - Revision 1.22 2002-09-07 15:25:02 peter + Revision 1.23 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.22 2002/09/07 15:25:02 peter * old logs removed and tabs fixed Revision 1.21 2002/09/07 11:50:02 jonas diff --git a/compiler/ncgcnv.pas b/compiler/ncgcnv.pas index 9754e93821..d6ae28ea08 100644 --- a/compiler/ncgcnv.pas +++ b/compiler/ncgcnv.pas @@ -213,7 +213,7 @@ interface begin location_release(exprasmlist,left.location); location.reference.base:=rg.getaddressregister(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR, + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR, left.location.register,location.reference.base); end else @@ -221,8 +221,8 @@ interface end; LOC_CREGISTER : begin - location.reference.base:=rg.getregisterint(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register, + location.reference.base:=rg.getaddressregister(exprasmlist); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register, location.reference.base); end; LOC_REFERENCE, @@ -361,7 +361,7 @@ interface begin location_release(exprasmlist,left.location); location.register:=rg.getaddressregister(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR, + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR, left.location.register,location.register); end else @@ -396,14 +396,14 @@ interface LOC_REFERENCE: begin location_release(exprasmlist,left.location); - location.register:=rg.getregisterint(exprasmlist); + location.register:=rg.getaddressregister(exprasmlist); cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.register); location_freetemp(exprasmlist,left.location); end; LOC_CREGISTER: begin - location.register:=rg.getregisterint(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register,location.register); + location.register:=rg.getaddressregister(exprasmlist); + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,location.register); end; LOC_REGISTER: location.register:=left.location.register; @@ -503,7 +503,12 @@ end. { $Log$ - Revision 1.31 2002-09-16 13:08:44 jonas + Revision 1.32 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.31 2002/09/16 13:08:44 jonas * big endian fix for second_int_to_int Revision 1.30 2002/09/07 15:25:02 peter diff --git a/compiler/ncginl.pas b/compiler/ncginl.pas index d44d984cee..6dcba487fe 100644 --- a/compiler/ncginl.pas +++ b/compiler/ncginl.pas @@ -475,7 +475,7 @@ implementation LOC_CREGISTER, LOC_REGISTER: begin - cg.a_load_reg_reg(exprasmlist,OS_INT, + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT, tcallparanode(tcallparanode(left).right).left.location.register,hregister); end; LOC_REFERENCE: @@ -604,7 +604,12 @@ end. { $Log$ - Revision 1.13 2002-08-13 18:01:52 carl + Revision 1.14 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.13 2002/08/13 18:01:52 carl * rename swatoperands to swapoperands + m68k first compilable version (still needs a lot of testing): assembler generator, system information , inline diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 96d8e6387f..3f58a361f2 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -137,7 +137,7 @@ implementation { the called procedure isn't allowed to change } { any register except EAX } cg.a_call_name(exprasmlist,'FPC_RELOCATE_THREADVAR'); - cg.a_load_reg_reg(exprasmlist,OS_INT,accumulator,location.reference.base); + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_ADDR,accumulator,location.reference.base); rg.restoreusedregisters(exprasmlist,pushed); end { normal variable } @@ -946,7 +946,12 @@ begin end. { $Log$ - Revision 1.29 2002-09-07 15:25:03 peter + Revision 1.30 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.29 2002/09/07 15:25:03 peter * old logs removed and tabs fixed Revision 1.28 2002/09/01 19:26:32 peter diff --git a/compiler/ncgmat.pas b/compiler/ncgmat.pas index a7b696a177..ce9295fa4d 100644 --- a/compiler/ncgmat.pas +++ b/compiler/ncgmat.pas @@ -182,7 +182,7 @@ implementation LOC_CREGISTER: begin location.register:=rg.getregisterint(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_INT,left.location.register, + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,left.location.register, location.register); cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register, location.register); @@ -454,7 +454,12 @@ begin end. { $Log$ - Revision 1.3 2002-08-23 16:14:48 peter + Revision 1.4 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.3 2002/08/23 16:14:48 peter * tempgen cleanup * tt_noreuse temp type added that will be used in genentrycode diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 44d4603dfa..fbfed4916a 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -147,7 +147,7 @@ implementation begin location_release(exprasmlist,left.location); location.reference.base := rg.getaddressregister(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register, + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register, location.reference.base); end else @@ -239,7 +239,7 @@ implementation begin location_release(exprasmlist,left.location); location.reference.base := rg.getaddressregister(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR,left.location.register, + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register, location.reference.base); end else @@ -284,7 +284,7 @@ implementation begin location_release(exprasmlist,left.location); location.reference.base:=rg.getaddressregister(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_ADDR, + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR, left.location.register,location.reference.base); end else @@ -864,7 +864,12 @@ begin end. { $Log$ - Revision 1.27 2002-09-07 15:25:03 peter + Revision 1.28 2002-09-17 18:54:02 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.27 2002/09/07 15:25:03 peter * old logs removed and tabs fixed Revision 1.26 2002/09/01 18:46:01 peter diff --git a/compiler/ncgset.pas b/compiler/ncgset.pas index 57991f5643..894060caf9 100644 --- a/compiler/ncgset.pas +++ b/compiler/ncgset.pas @@ -295,7 +295,7 @@ implementation if ranges then begin pleftreg:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,pleftreg); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,pleftreg); if opsize <> OS_INT then cg.a_op_const_reg(exprasmlist,OP_AND,255,pleftreg); opsize := OS_INT; @@ -417,7 +417,7 @@ implementation LOC_CREGISTER: begin { load set value into register } - cg.a_load_reg_reg(exprasmlist,OS_32, + cg.a_load_reg_reg(exprasmlist,OS_32,OS_32, right.location.register,hr); end; LOC_REFERENCE, @@ -444,9 +444,9 @@ implementation LOC_CREGISTER: begin hr3:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hr3); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr3); hr:=cg.get_scratch_reg_int(exprasmlist); - cg.a_load_reg_reg(exprasmlist,OS_INT,hr3,hr); + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,hr3,hr); end; else begin @@ -514,7 +514,7 @@ implementation LOC_CREGISTER: begin hr:=rg.makeregsize(left.location.register,OS_INT); - cg.a_load_reg_reg(exprasmlist,left.location.size,left.location.register,hr); + cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr); cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_BE,31,hr,l); { reset of result register is done in routine entry } cg.a_jmp_always(exprasmlist,l2); @@ -573,7 +573,7 @@ implementation cg.a_param_ref(exprasmlist,OS_ADDR,right.location.reference,paramanager.getintparaloc(1)); cg.a_call_name(exprasmlist,'FPC_SET_IN_BYTE'); { result of value is always one full register } - cg.a_load_reg_reg(exprasmlist,OS_INT,ACCUMULATOR,location.register); + cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,ACCUMULATOR,location.register); { release the allocated register } if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then rg.ungetregisterint(exprasmlist,pleftreg); @@ -622,7 +622,7 @@ implementation to move the result before subtract to a help register. } - cg.a_load_reg_reg(exprasmlist, opsize, hregister, scratch_reg); + cg.a_load_reg_reg(exprasmlist, opsize, opsize, hregister, scratch_reg); cg.a_op_const_reg(exprasmlist, OP_SUB, value, hregister); end; @@ -993,7 +993,12 @@ begin end. { $Log$ - Revision 1.19 2002-09-16 18:08:26 peter + Revision 1.20 2002-09-17 18:54:03 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.19 2002/09/16 18:08:26 peter * fix last optimization in genlinearlist, detected by bug tw1066 * use generic casenode.pass2 routine and override genlinearlist * add jumptable support to generic casenode, by default there is diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 60f243148e..1589137472 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -286,7 +286,7 @@ implementation if l.loc=LOC_REGISTER then begin hregister:=rg.makeregsize(l.registerlow,OS_INT); - cg.a_load_reg_reg(list,l.size,l.registerlow,hregister); + cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister); end else hregister:=rg.getregisterint(list); @@ -1302,7 +1302,7 @@ implementation LOC_CREGISTER, LOC_REGISTER: // if not(hp.paraloc.size in [OS_S64,OS_64]) then - cg.a_load_reg_reg(list,hp.paraloc.size,hp.paraloc.register,tvarsym(hp.parasym).reg); + cg.a_load_reg_reg(list,hp.paraloc.size,OS_32,hp.paraloc.register,tvarsym(hp.parasym).reg); // else // cg64.a_load64_reg_reg(list,hp.paraloc.register64,tvarsym(hp.parasym).reg); LOC_CFPUREGISTER, @@ -1633,7 +1633,7 @@ implementation if is_object(procinfo._class) then begin cg.a_reg_alloc(list,accumulator); - cg.a_load_reg_reg(list,OS_ADDR,self_pointer_reg,accumulator); + cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,self_pointer_reg,accumulator); usesacc:=true; end; {$ifdef i386} @@ -1831,7 +1831,12 @@ implementation end. { $Log$ - Revision 1.49 2002-09-10 21:48:30 florian + Revision 1.50 2002-09-17 18:54:03 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.49 2002/09/10 21:48:30 florian * improved handling of procedures with register calling conventions Revision 1.48 2002/09/07 15:25:03 peter diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index 6a565bd406..95a53aa585 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -59,7 +59,7 @@ unit cgcpu; procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);override; procedure a_load_reg_ref(list : taasmoutput; size: tcgsize; reg : tregister;const ref : treference);override; procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const Ref : treference;reg : tregister);override; - procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);override; + procedure a_load_reg_reg(list : taasmoutput;fromsize, tosize : tcgsize;reg1,reg2 : tregister);override; { fpu move instructions } procedure a_loadfpu_reg_reg(list: taasmoutput; reg1, reg2: tregister); override; @@ -391,13 +391,16 @@ const end; - procedure tcgppc.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister); + procedure tcgppc.a_load_reg_reg(list : taasmoutput;fromsize, tosize : tcgsize;reg1,reg2 : tregister); begin if (reg1 <> reg2) or - not(size in [OS_32,OS_S32]) then + (tcgsize2size[tosize] < tcgsize2size[fromsize]) or + ((tcgsize2size[tosize] = tcgsize2size[fromsize]) and + (tosize <> fromsize) and + not(fromsize in [OS_32,OS_S32])) then begin - case size of + case fromsize of OS_8: list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM, reg2,reg1,0,31-8+1,31)); @@ -583,7 +586,7 @@ const internalerror(200208103) else if (a = 1) then begin - a_load_reg_reg(list,OS_INT,src,dst); + a_load_reg_reg(list,OS_INT,OS_INT,src,dst); exit end else if ispowerof2(a,l1) then @@ -609,7 +612,7 @@ const end else if (a = 1) then begin - a_load_reg_reg(list,OS_INT,src,dst); + a_load_reg_reg(list,OS_INT,OS_INT,src,dst); exit end else if ispowerof2(a,l1) then @@ -1708,7 +1711,7 @@ const end else begin - cg.a_load_reg_reg(list,OS_INT,regsrc.reglo,regdst.reglo); + cg.a_load_reg_reg(list,OS_INT,OS_INT,regsrc.reglo,regdst.reglo); cg.a_op_const_reg_reg(list,op,OS_32,value shr 32,regsrc.reghi, regdst.reghi); end; @@ -1725,7 +1728,12 @@ begin end. { $Log$ - Revision 1.57 2002-09-10 21:22:25 jonas + Revision 1.58 2002-09-17 18:54:06 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.57 2002/09/10 21:22:25 jonas + added some internal errors * fixed bug in sysv exit code diff --git a/compiler/powerpc/cpubase.pas b/compiler/powerpc/cpubase.pas index 6c67cb7d1f..03ce44dd50 100644 --- a/compiler/powerpc/cpubase.pas +++ b/compiler/powerpc/cpubase.pas @@ -372,9 +372,20 @@ uses { overlay a 64 Bit register type } 3 : (reg64 : tregister64); 4 : (register64 : tregister64); - ); + ); end; + treglocation = packed record + case longint of + 1 : (register,registerhigh : tregister); + { overlay a registerlow } + 2 : (registerlow : tregister); + { overlay a 64 Bit register type } + 3 : (reg64 : tregister64); + 4 : (register64 : tregister64); + end; + + tlocation = packed record size : TCGSize; loc : tloc; @@ -710,7 +721,12 @@ implementation end. { $Log$ - Revision 1.33 2002-09-07 17:54:59 florian + Revision 1.34 2002-09-17 18:54:06 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.33 2002/09/07 17:54:59 florian * first part of PowerPC fixes Revision 1.32 2002/09/07 15:25:14 peter diff --git a/compiler/powerpc/nppccnv.pas b/compiler/powerpc/nppccnv.pas index f638c5f271..44058a9836 100644 --- a/compiler/powerpc/nppccnv.pas +++ b/compiler/powerpc/nppccnv.pas @@ -32,7 +32,7 @@ interface type tppctypeconvnode = class(tcgtypeconvnode) protected - procedure second_int_to_int;override; + { procedure second_int_to_int;override; } { procedure second_string_to_string;override; } { procedure second_cstring_to_pchar;override; } { procedure second_string_to_chararray;override; } @@ -109,38 +109,6 @@ implementation SecondTypeConv *****************************************************************************} - procedure tppctypeconvnode.second_int_to_int; - var - newsize : tcgsize; - size, leftsize : cardinal; - begin - newsize:=def_cgsize(resulttype.def); - - { insert range check if not explicit conversion } - if not(nf_explizit in flags) then - cg.g_rangecheck(exprasmlist,left,resulttype.def); - - { is the result size smaller ? } - size := resulttype.def.size; - leftsize := left.resulttype.def.size; - if (size < leftsize) or - (((newsize in [OS_64,OS_S64]) or - (left.location.loc <> LOC_REGISTER)) and - (size > leftsize)) then - begin - { reuse the left location by default } - location_copy(location,left.location); - location_force_reg(exprasmlist,location,newsize,false); - end - else - begin - { no special loading is required, reuse current location } - location_copy(location,left.location); - location.size:=newsize; - end; - end; - - procedure tppctypeconvnode.second_int_to_real; type @@ -422,7 +390,12 @@ begin end. { $Log$ - Revision 1.24 2002-08-23 16:14:50 peter + Revision 1.25 2002-09-17 18:54:06 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.24 2002/08/23 16:14:50 peter * tempgen cleanup * tt_noreuse temp type added that will be used in genentrycode diff --git a/compiler/sparc/cgcpu.pas b/compiler/sparc/cgcpu.pas index 4b523da7f1..99963a7fb6 100644 --- a/compiler/sparc/cgcpu.pas +++ b/compiler/sparc/cgcpu.pas @@ -59,7 +59,7 @@ specific processor ABI. It is overriden for each CPU target. PROCEDURE a_load_const_ref(list:TAasmOutput;size:tcgsize;a:aword;CONST ref:TReference);OVERRIDE; PROCEDURE a_load_reg_ref(list:TAasmOutput;size:tcgsize;reg:tregister;CONST ref:TReference);OVERRIDE; PROCEDURE a_load_ref_reg(list:TAasmOutput;size:tcgsize;CONST ref:TReference;reg:tregister);OVERRIDE; - PROCEDURE a_load_reg_reg(list:TAasmOutput;size:tcgsize;reg1,reg2:tregister);OVERRIDE; + PROCEDURE a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);OVERRIDE; PROCEDURE a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);OVERRIDE; { fpu move instructions } PROCEDURE a_loadfpu_reg_reg(list:TAasmOutput;reg1, reg2:tregister);OVERRIDE; @@ -206,7 +206,7 @@ PROCEDURE tcgSPARC.a_load_ref_reg(list:TAasmOutput;size:tcgsize;CONST ref:TRefer end; - PROCEDURE tcgSPARC.a_load_reg_reg(list:TAasmOutput;size:tcgsize;reg1,reg2:tregister); + PROCEDURE tcgSPARC.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister); var op:tasmop; @@ -505,7 +505,7 @@ PROCEDURE tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste else regloadsize := OS_32; end; tmpreg := get_scratch_reg(list); - a_load_reg_reg(list,reg.regloadsize,src,tmpreg); + a_load_reg_reg(list,regloadsize,OS_32,src,tmpreg); end; if not(src in [R_ECX,R_CX,R_CL]) then begin @@ -520,7 +520,7 @@ PROCEDURE tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste list.concat(taicpu.op_reg(A_SAVE,S_L,R_ECX)); popecx := true; end; - a_load_reg_reg(list,OS_8,(src),R_CL); + a_load_reg_reg(list,OS_8,OS_8,(src),R_CL); end else src := R_CL; @@ -533,7 +533,7 @@ PROCEDURE tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],S_L, R_CL,tmpreg)); { move result back to the destination } - a_load_reg_reg(list,OS_32,tmpreg,R_ECX); + a_load_reg_reg(list,OS_32,OS_32,tmpreg,R_ECX); free_scratch_reg(list,tmpreg); end; if popecx then @@ -637,7 +637,7 @@ PROCEDURE tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste end; OP_ADD, OP_SUB: if (a = 0) then - a_load_reg_reg(list,size,src,dst) + a_load_reg_reg(list,size,size,src,dst) else begin reference_reset(tmpref); @@ -765,7 +765,7 @@ PROCEDURE tcgSPARC.g_flags2reg(list:TAasmOutput;Size:TCgSize;CONST f:tresflags;r list.concat(ai); IF hreg<>reg THEN - a_load_reg_reg(list,OS_8,hreg,reg); + a_load_reg_reg(list,OS_8,OS_8,hreg,reg); END; { *********** entry/exit code and address loading ************ } diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 3c1a7c554d..1b5c977e6b 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -69,7 +69,7 @@ unit cgx86; procedure a_load_const_ref(list : taasmoutput; size: tcgsize; a : aword;const ref : treference);override; procedure a_load_reg_ref(list : taasmoutput; size: tcgsize; reg : tregister;const ref : treference);override; procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;reg : tregister);override; - procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);override; + procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override; procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);override; { fpu move instructions } @@ -474,14 +474,14 @@ unit cgx86; end; - procedure tcgx86.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister); + procedure tcgx86.a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister); var op: tasmop; s: topsize; begin - sizes2load(size,reg2opsize[reg2],op,s); + sizes2load(fromsize,reg2opsize[reg2],op,s); if (rg.makeregsize(reg1,OS_INT) = rg.makeregsize(reg2,OS_INT)) then begin { "mov reg1, reg1" doesn't make sense } @@ -490,7 +490,7 @@ unit cgx86; { optimize movzx with "and ffff," operation } if (op = A_MOVZX) then begin - case size of + case fromsize of OS_8: begin list.concat(taicpu.op_const_reg(A_AND,reg2opsize[reg2],255,reg2)); @@ -794,7 +794,7 @@ unit cgx86; else regloadsize := OS_32; end; tmpreg := get_scratch_reg_int(list); - a_load_reg_reg(list,regloadsize,src,tmpreg); + a_load_reg_reg(list,regloadsize,regloadsize,src,tmpreg); end; if not(src in [R_ECX,R_CX,R_CL]) then begin @@ -809,7 +809,7 @@ unit cgx86; list.concat(taicpu.op_reg(A_PUSH,S_L,R_ECX)); popecx := true; end; - a_load_reg_reg(list,OS_32,rg.makeregsize(src,OS_32),R_ECX); + a_load_reg_reg(list,OS_32,OS_32,rg.makeregsize(src,OS_32),R_ECX); end else src := R_CL; @@ -822,7 +822,7 @@ unit cgx86; list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],S_L, R_CL,tmpreg)); { move result back to the destination } - a_load_reg_reg(list,OS_32,tmpreg,R_ECX); + a_load_reg_reg(list,OS_32,OS_32,tmpreg,R_ECX); free_scratch_reg(list,tmpreg); end; if popecx then @@ -925,7 +925,7 @@ unit cgx86; end; OP_ADD, OP_SUB: if (a = 0) then - a_load_reg_reg(list,size,src,dst) + a_load_reg_reg(list,size,size,src,dst) else begin reference_reset(tmpref); @@ -1054,7 +1054,7 @@ unit cgx86; ai.SetCondition(flags_to_cond(f)); list.concat(ai); if (reg <> hreg) then - a_load_reg_reg(list,OS_8,hreg,reg); + a_load_reg_reg(list,OS_8,OS_8,hreg,reg); end; @@ -1155,7 +1155,7 @@ unit cgx86; { was earlier XCHG, of course nonsense } begin rg.getexplicitregisterint(list,R_EDI); - a_load_reg_reg(list,OS_32,reg32,R_EDI); + a_load_reg_reg(list,OS_32,OS_32,reg32,R_EDI); end; a_load_ref_reg(list,OS_8,srcref,reg8); If delsource and (len=1) then @@ -1163,7 +1163,7 @@ unit cgx86; a_load_reg_ref(list,OS_8,reg8,dstref); if swap then begin - a_load_reg_reg(list,OS_32,R_EDI,reg32); + a_load_reg_reg(list,OS_32,OS_32,R_EDI,reg32); rg.ungetregisterint(list,R_EDI); end else @@ -1681,7 +1681,12 @@ unit cgx86; end. { $Log$ - Revision 1.16 2002-09-16 19:08:47 peter + Revision 1.17 2002-09-17 18:54:06 jonas + * a_load_reg_reg() now has two size parameters: source and dest. This + allows some optimizations on architectures that don't encode the + register size in the register name. + + Revision 1.16 2002/09/16 19:08:47 peter * support references without registers and symbol in paramref_addr. It pushes only the offset