diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 153eecf212..ff9bac2495 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -2534,7 +2534,7 @@ implementation LOC_REGISTER,LOC_CREGISTER: begin { paramfpu_ref does the check_simpe_location check here if necessary } - tg.GetTemp(list,TCGSize2Size[size],tt_normal,ref); + tg.GetTemp(list,TCGSize2Size[size],TCGSize2Size[size],tt_normal,ref); a_loadfpu_reg_ref(list,size,size,r,ref); a_paramfpu_ref(list,size,ref,cgpara); tg.Ungettemp(list,ref); @@ -3670,7 +3670,7 @@ implementation if size>0 then begin - tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref); + tg.GetTemp(list,size,sizeof(aint),tt_noreuse,current_procinfo.save_regs_ref); include(current_procinfo.flags,pi_has_saved_regs); { Copy registers to temp } diff --git a/compiler/globals.pas b/compiler/globals.pas index e7fa38dd5d..d422306916 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -265,7 +265,8 @@ interface { Memory sizes } heapsize, stacksize, - jmp_buf_size : longint; + jmp_buf_size, + jmp_buf_align : longint; {$Ifdef EXTDEBUG} { parameter switches } diff --git a/compiler/ncgbas.pas b/compiler/ncgbas.pas index 0fe45fa461..4c934cb150 100644 --- a/compiler/ncgbas.pas +++ b/compiler/ncgbas.pas @@ -429,7 +429,7 @@ interface else begin location_reset(tempinfo^.location,LOC_REFERENCE,def_cgsize(tempinfo^.typedef)); - tg.GetTemp(current_asmdata.CurrAsmList,size,tempinfo^.temptype,tempinfo^.location.reference); + tg.GetTemp(current_asmdata.CurrAsmList,size,tempinfo^.typedef.alignment,tempinfo^.temptype,tempinfo^.location.reference); end; include(tempinfo^.flags,ti_valid); end; diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 9b16329536..79d17f36b0 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -555,7 +555,7 @@ implementation structs with up to 16 bytes are returned in registers } if cgsize in [OS_128,OS_S128] then begin - tg.GetTemp(current_asmdata.CurrAsmList,16,tt_normal,ref); + tg.GetTemp(current_asmdata.CurrAsmList,16,8,tt_normal,ref); location_reset(location,LOC_REFERENCE,OS_NO); location.reference:=ref; cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_64,OS_64,procdefinition.funcretloc[callerside].register,ref); diff --git a/compiler/ncgcnv.pas b/compiler/ncgcnv.pas index 6649e927ae..8304ce5c33 100644 --- a/compiler/ncgcnv.pas +++ b/compiler/ncgcnv.pas @@ -243,7 +243,7 @@ interface case tstringdef(resultdef).stringtype of st_shortstring : begin - tg.GetTemp(current_asmdata.CurrAsmList,256,tt_normal,location.reference); + tg.GetTemp(current_asmdata.CurrAsmList,256,1,tt_normal,location.reference); cg.a_load_loc_ref(current_asmdata.CurrAsmList,left.location.size,left.location, location.reference); location_freetemp(current_asmdata.CurrAsmList,left.location); @@ -272,7 +272,7 @@ interface if (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then location_force_fpureg(current_asmdata.CurrAsmList,left.location,false); { round them down to the proper precision } - tg.gettemp(current_asmdata.currasmlist,resultdef.size,tt_normal,tr); + tg.gettemp(current_asmdata.currasmlist,resultdef.size,resultdef.alignment,tt_normal,tr); cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,tr); location_reset(left.location,LOC_REFERENCE,location.size); left.location.reference:=tr; @@ -368,7 +368,7 @@ interface var r:Treference; begin - tg.gettemp(current_asmdata.currasmlist,2*sizeof(puint),tt_normal,r); + tg.gettemp(current_asmdata.currasmlist,2*sizeof(puint),sizeof(puint),tt_normal,r); location_reset(location,LOC_REFERENCE,OS_NO); location.reference:=r; cg.a_load_const_ref(current_asmdata.currasmlist,OS_ADDR,0,r); diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index d571664921..818161a1db 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -1323,7 +1323,7 @@ implementation end else begin - tg.GetTemp(current_asmdata.CurrAsmList,sizeof(pint),tt_normal,exceptref); + tg.GetTemp(current_asmdata.CurrAsmList,sizeof(pint),sizeof(pint),tt_normal,exceptref); cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,exceptref); end; diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 8501462597..5be528d911 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -432,7 +432,7 @@ implementation {$else} internalerror(20020520); {$endif} {$endif} - tg.GetTemp(current_asmdata.CurrAsmList,2*sizeof(pint),tt_normal,location.reference); + tg.GetTemp(current_asmdata.CurrAsmList,2*sizeof(pint),sizeof(pint),tt_normal,location.reference); secondpass(left); { load class instance/classrefdef address } @@ -757,7 +757,7 @@ implementation { convert an extended into a double/single, since sse } { doesn't support extended) } r:=cg.getfpuregister(current_asmdata.CurrAsmList,right.location.size); - tg.gettemp(current_asmdata.CurrAsmList,left.resultdef.size,tt_normal,href); + tg.gettemp(current_asmdata.CurrAsmList,left.resultdef.size,left.resultdef.alignment,tt_normal,href); cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,right.location.size,right.location.size,right.location.reference,r); cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,right.location.size,left.location.size,r,href); if releaseright then @@ -834,7 +834,7 @@ implementation begin { perform size conversion if needed (the mm-code cannot convert an } { extended into a double/single, since sse doesn't support extended) } - tg.gettemp(current_asmdata.CurrAsmList,left.resultdef.size,tt_normal,href); + tg.gettemp(current_asmdata.CurrAsmList,left.resultdef.size,left.resultdef.alignment,tt_normal,href); cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,right.location.size,left.location.size,right.location.register,href); location_reset(right.location,LOC_REFERENCE,left.location.size); right.location.reference:=href; @@ -951,31 +951,38 @@ implementation hp : tarrayconstructornode; href : treference; lt : tdef; - vaddr : boolean; - vtype : longint; - freetemp, - dovariant : boolean; - elesize : longint; - tmpreg : tregister; paraloc : tcgparalocation; otlabel, oflabel : tasmlabel; + vtype : longint; + elesize, + elealign : longint; + tmpreg : tregister; + vaddr : boolean; + freetemp, + dovariant : boolean; begin if is_packed_array(resultdef) then internalerror(200608042); dovariant:=(nf_forcevaria in flags) or is_variant_array(resultdef); if dovariant then - elesize:=sizeof(pint)+sizeof(pint) + begin + elesize:=sizeof(pint)+sizeof(pint); + elealign:=sizeof(pint); + end else - elesize:=tarraydef(resultdef).elesize; + begin + elesize:=tarraydef(resultdef).elesize; + elealign:=tarraydef(resultdef).elementdef.alignment; + end; location_reset(location,LOC_CREFERENCE,OS_NO); fillchar(paraloc,sizeof(paraloc),0); { Allocate always a temp, also if no elements are required, to be sure that location is valid (PFV) } if tarraydef(resultdef).highrange=-1 then - tg.GetTemp(current_asmdata.CurrAsmList,elesize,tt_normal,location.reference) + tg.GetTemp(current_asmdata.CurrAsmList,elesize,elealign,tt_normal,location.reference) else - tg.GetTemp(current_asmdata.CurrAsmList,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference); + tg.GetTemp(current_asmdata.CurrAsmList,(tarraydef(resultdef).highrange+1)*elesize,resultdef.alignment,tt_normal,location.reference); href:=location.reference; { Process nodes in array constructor } hp:=self; diff --git a/compiler/ncgmat.pas b/compiler/ncgmat.pas index a501fccc94..ee4441d7a3 100644 --- a/compiler/ncgmat.pas +++ b/compiler/ncgmat.pas @@ -149,7 +149,7 @@ implementation { get a temporary memory reference to store the floating point value } - tg.gettemp(current_asmdata.CurrAsmList,tcgsize2size[_size],tt_normal,href); + tg.gettemp(current_asmdata.CurrAsmList,tcgsize2size[_size],tcgsize2size[_size],tt_normal,href); { store the floating point value in the temporary memory area } cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,_size,_size,r,href); { only single and double ieee are supported, for little endian diff --git a/compiler/ncgopt.pas b/compiler/ncgopt.pas index e235463aab..cb2b8d96fd 100644 --- a/compiler/ncgopt.pas +++ b/compiler/ncgopt.pas @@ -90,7 +90,7 @@ begin if not(tg.istemp(left.location.reference) and (tg.sizeoftemp(current_asmdata.CurrAsmList,left.location.reference) = 256)) then begin - tg.Gettemp(current_asmdata.CurrAsmList,256,tt_normal,href); + tg.Gettemp(current_asmdata.CurrAsmList,256,1,tt_normal,href); cg.g_copyshortstring(current_asmdata.CurrAsmList,left.location.reference,href,255); location_freetemp(current_asmdata.CurrAsmList,left.location); { return temp reference } diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 95a6b9a27b..0d6b1a0e7d 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -361,10 +361,11 @@ implementation begin srsym:=search_system_type('JMP_BUF'); jmp_buf_size:=srsym.typedef.size; + jmp_buf_align:=srsym.typedef.alignment; end; - tg.GetTemp(list,EXCEPT_BUF_SIZE,tt_persistent,t.envbuf); - tg.GetTemp(list,jmp_buf_size,tt_persistent,t.jmpbuf); - tg.GetTemp(list,sizeof(pint),tt_persistent,t.reasonbuf); + tg.GetTemp(list,EXCEPT_BUF_SIZE,sizeof(pint),tt_persistent,t.envbuf); + tg.GetTemp(list,jmp_buf_size,jmp_buf_align,tt_persistent,t.jmpbuf); + tg.GetTemp(list,sizeof(pint),sizeof(pint),tt_persistent,t.reasonbuf); end; @@ -682,7 +683,7 @@ implementation { if it's in an mm register, store to memory first } if (l.loc in [LOC_MMREGISTER,LOC_CMMREGISTER]) then begin - tg.GetTemp(list,tcgsize2size[l.size],tt_normal,href); + tg.GetTemp(list,tcgsize2size[l.size],tcgsize2size[l.size],tt_normal,href); cg.a_loadmm_reg_ref(list,l.size,l.size,l.register,href,mms_movescalar); location_reset(l,LOC_REFERENCE,l.size); l.reference:=href; @@ -707,7 +708,7 @@ implementation { if it's in an fpu register, store to memory first } if (l.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then begin - tg.GetTemp(list,tcgsize2size[l.size],tt_normal,href); + tg.GetTemp(list,tcgsize2size[l.size],tcgsize2size[l.size],tt_normal,href); cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,href); location_reset(l,LOC_REFERENCE,l.size); l.reference:=href; @@ -771,7 +772,7 @@ implementation LOC_FPUREGISTER, LOC_CFPUREGISTER : begin - tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r); + tg.GetTemp(list,TCGSize2Size[l.size],TCGSize2Size[l.size],tt_normal,r); cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,r); location_reset(l,LOC_REFERENCE,l.size); l.reference:=r; @@ -779,7 +780,7 @@ implementation LOC_MMREGISTER, LOC_CMMREGISTER: begin - tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r); + tg.GetTemp(list,TCGSize2Size[l.size],TCGSize2Size[l.size],tt_normal,r); cg.a_loadmm_reg_ref(list,l.size,l.size,l.register,r,mms_movescalar); location_reset(l,LOC_REFERENCE,l.size); l.reference:=r; @@ -788,7 +789,7 @@ implementation LOC_REGISTER, LOC_CREGISTER : begin - tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r); + tg.GetTemp(list,TCGSize2Size[l.size],TCGSize2Size[l.size],tt_normal,r); {$ifndef cpu64bitalu} if l.size in [OS_64,OS_S64] then cg64.a_load64_loc_ref(list,l,r) @@ -803,7 +804,7 @@ implementation LOC_SUBSETREF, LOC_CSUBSETREF: begin - tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r); + tg.GetTemp(list,TCGSize2Size[l.size],TCGSize2Size[l.size],tt_normal,r); cg.a_load_loc_ref(list,l.size,l,r); location_reset(l,LOC_REFERENCE,l.size); l.reference:=r; @@ -1828,7 +1829,7 @@ implementation { Arm and Sparc passes floats in int registers, when loading to fpu register we need a temp } sizeleft := TCGSize2Size[currpara.initialloc.size]; - tg.GetTemp(list,sizeleft,tt_normal,tempref); + tg.GetTemp(list,sizeleft,sizeleft,tt_normal,tempref); href:=tempref; while assigned(paraloc) do begin diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 1d201bd341..be91952a56 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -340,7 +340,7 @@ implementation newparaloc^.register:=cg.getmmregister(list,paraloc^.size); LOC_REFERENCE : begin - tg.gettemp(list,len,tt_persistent,href); + tg.gettemp(list,len,cgpara.alignment,tt_persistent,href); newparaloc^.reference.index:=href.base; newparaloc^.reference.offset:=href.offset; end; diff --git a/compiler/powerpc/nppccnv.pas b/compiler/powerpc/nppccnv.pas index 2ebf63ac52..ab3dfc44f7 100644 --- a/compiler/powerpc/nppccnv.pas +++ b/compiler/powerpc/nppccnv.pas @@ -144,7 +144,7 @@ implementation { stw R3,disp+4(R1) # store lower half } { lfd FR1,disp(R1) # float load double of value } { fsub FR1,FR1,FR2 # subtract 0x4330000000000000 } - tg.Gettemp(current_asmdata.CurrAsmList,8,tt_normal,ref); + tg.Gettemp(current_asmdata.CurrAsmList,8,8,tt_normal,ref); signed := is_signed(left.resultdef); diff --git a/compiler/powerpc64/nppccnv.pas b/compiler/powerpc64/nppccnv.pas index e3b75c0c10..be1855a979 100644 --- a/compiler/powerpc64/nppccnv.pas +++ b/compiler/powerpc64/nppccnv.pas @@ -125,7 +125,7 @@ begin { fcfid frD,frD # point integer (no round) } { fmadd frD,frC,frT1,frD # (2^32)*high + low } { # (only add can round) } - tg.Gettemp(current_asmdata.CurrAsmList, 8, tt_normal, disp); + tg.Gettemp(current_asmdata.CurrAsmList, 8, 8, tt_normal, disp); { do the signed case for everything but 64 bit unsigned integers } signed := (left.location.size <> OS_64); @@ -143,7 +143,7 @@ begin internalerror(200110011); // allocate second temp memory - tg.Gettemp(current_asmdata.CurrAsmList, 8, tt_normal, disp2); + tg.Gettemp(current_asmdata.CurrAsmList, 8, 8, tt_normal, disp2); end; if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) then diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas index 337e21e32a..b31363372e 100644 --- a/compiler/rgobj.pas +++ b/compiler/rgobj.pas @@ -1718,6 +1718,7 @@ unit rgobj; spill_temps : ^Tspill_temp_list; supreg : tsuperregister; templist : TAsmList; + size: ptrint; begin spill_registers:=false; live_registers.clear; @@ -1739,9 +1740,10 @@ unit rgobj; {Get a temp for the spilled register, the size must at least equal a complete register, take also care of the fact that subreg can be larger than a single register like doubles that occupy 2 registers } + size:=max(tcgsize2size[reg_cgsize(newreg(regtype,t,R_SUBWHOLE))], + tcgsize2size[reg_cgsize(newreg(regtype,t,reginfo[t].subreg))]); tg.gettemp(templist, - max(tcgsize2size[reg_cgsize(newreg(regtype,t,R_SUBWHOLE))], - tcgsize2size[reg_cgsize(newreg(regtype,t,reginfo[t].subreg))]), + size,size, tt_noreuse,spill_temps^[t]); end; list.insertlistafter(headertai,templist); diff --git a/compiler/sparc/cgcpu.pas b/compiler/sparc/cgcpu.pas index 9dd00e129a..daba565d57 100644 --- a/compiler/sparc/cgcpu.pas +++ b/compiler/sparc/cgcpu.pas @@ -423,7 +423,7 @@ implementation var href : treference; begin - tg.GetTemp(list,TCGSize2Size[size],tt_normal,href); + tg.GetTemp(list,TCGSize2Size[size],TCGSize2Size[size],tt_normal,href); a_loadfpu_reg_ref(list,size,size,r,href); a_paramfpu_ref(list,size,href,paraloc); tg.Ungettemp(list,href); diff --git a/compiler/tgobj.pas b/compiler/tgobj.pas index 35f8033209..c83ef9507d 100644 --- a/compiler/tgobj.pas +++ b/compiler/tgobj.pas @@ -80,7 +80,7 @@ unit tgobj; } procedure setfirsttemp(l : longint); - procedure gettemp(list: TAsmList; size : longint;temptype:ttemptype;out ref : treference); + procedure gettemp(list: TAsmList; size, alignment : longint;temptype:ttemptype;out ref : treference); procedure gettemptyped(list: TAsmList; def:tdef;temptype:ttemptype;out ref : treference); procedure ungettemp(list: TAsmList; const ref : treference); @@ -491,17 +491,17 @@ implementation end; - procedure ttgobj.gettemp(list: TAsmList; size : longint;temptype:ttemptype;out ref : treference); + procedure ttgobj.gettemp(list: TAsmList; size, alignment : longint;temptype:ttemptype;out ref : treference); var varalign : shortint; begin - varalign:=size_2_align(size); - varalign:=used_align(varalign,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax); + varalign:=used_align(alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax); { can't use reference_reset_base, because that will let tgobj depend on cgobj (PFV) } fillchar(ref,sizeof(ref),0); ref.base:=current_procinfo.framepointer; ref.offset:=alloctemp(list,size,varalign,temptype,nil); + ref.alignment:=varalign; end; @@ -516,6 +516,7 @@ implementation fillchar(ref,sizeof(ref),0); ref.base:=current_procinfo.framepointer; ref.offset:=alloctemp(list,def.size,varalign,temptype,def); + ref.alignment:=varalign; end; diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 37d71e735b..56a06f1c22 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -946,7 +946,7 @@ unit cgx86; (tosize