diff --git a/compiler/mips/cgcpu.pas b/compiler/mips/cgcpu.pas index f267d54b67..9c51b18092 100644 --- a/compiler/mips/cgcpu.pas +++ b/compiler/mips/cgcpu.pas @@ -49,8 +49,6 @@ type procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister); { parameter } - procedure a_load_const_cgpara(list: tasmlist; size: tcgsize; a: tcgint; const paraloc: TCGPara); override; - procedure a_load_ref_cgpara(list: tasmlist; sz: tcgsize; const r: TReference; const paraloc: TCGPara); override; procedure a_loadaddr_ref_cgpara(list: tasmlist; const r: TReference; const paraloc: TCGPara); override; procedure a_loadfpu_reg_cgpara(list: tasmlist; size: tcgsize; const r: tregister; const paraloc: TCGPara); override; procedure a_loadfpu_ref_cgpara(list: tasmlist; size: tcgsize; const ref: treference; const paraloc: TCGPara); override; @@ -543,60 +541,6 @@ begin end; -procedure TCGMIPS.a_load_const_cgpara(list: tasmlist; size: tcgsize; a: tcgint; const paraloc: TCGPara); -var - Ref: TReference; -begin - paraloc.check_simple_location; - paramanager.allocparaloc(list,paraloc.location); - case paraloc.location^.loc of - LOC_REGISTER, LOC_CREGISTER: - a_load_const_reg(list, size, a, paraloc.location^.Register); - LOC_REFERENCE: - begin - with paraloc.location^.Reference do - begin - if (Index = NR_SP) and (Offset < 0) then - InternalError(2002081104); - reference_reset_base(ref, index, offset, sizeof(aint)); - end; - a_load_const_ref(list, size, a, ref); - end; - else - InternalError(2002122200); - end; -end; - - -procedure TCGMIPS.a_load_ref_cgpara(list: tasmlist; sz: TCgSize; const r: TReference; const paraloc: TCGPara); -var - href, href2: treference; - hloc: pcgparalocation; -begin - href := r; - hloc := paraloc.location; - while assigned(hloc) do - begin - paramanager.allocparaloc(list,hloc); - case hloc^.loc of - LOC_REGISTER,LOC_CREGISTER: - a_load_ref_reg(list, hloc^.size, hloc^.size, href, hloc^.Register); - LOC_FPUREGISTER,LOC_CFPUREGISTER : - a_loadfpu_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register); - LOC_REFERENCE: - begin - reference_reset_base(href2, hloc^.reference.index, hloc^.reference.offset, sizeof(aint)); - a_load_ref_ref(list, hloc^.size, hloc^.size, href, href2); - end - else - internalerror(200408241); - end; - Inc(href.offset, tcgsize2size[hloc^.size]); - hloc := hloc^.Next; - end; -end; - - procedure TCGMIPS.a_loadaddr_ref_cgpara(list: tasmlist; const r: TReference; const paraloc: TCGPara); var Ref: TReference; @@ -630,6 +574,9 @@ var href, href2: treference; hloc: pcgparalocation; begin + { TODO: inherited cannot deal with individual locations for each of OS_32 registers. + Must change parameter management to allocate a single 64-bit register pair, + then this method can be removed. } href := ref; hloc := paraloc.location; while assigned(hloc) do @@ -642,8 +589,10 @@ begin a_loadfpu_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register); LOC_REFERENCE: begin - reference_reset_base(href2, hloc^.reference.index, hloc^.reference.offset, sizeof(aint)); - a_load_ref_ref(list, hloc^.size, hloc^.size, href, href2); + paraloc.check_simple_location; + reference_reset_base(href2,paraloc.location^.reference.index,paraloc.location^.reference.offset,paraloc.alignment); + { concatcopy should choose the best way to copy the data } + g_concatcopy(list,ref,href2,tcgsize2size[size]); end; else internalerror(200408241); diff --git a/compiler/mips/cpupara.pas b/compiler/mips/cpupara.pas index b04d7061fb..1cee0f1873 100644 --- a/compiler/mips/cpupara.pas +++ b/compiler/mips/cpupara.pas @@ -384,6 +384,17 @@ implementation paraloc^.size:=OS_32 else paraloc^.size:=paracgsize; + + { big-endian targets require that record data stored in parameter + registers is left-aligned } + if (target_info.endian=endian_big) and + (paradef.typ = recorddef) and + (tcgsize2size[paraloc^.size] <> sizeof(aint)) then + begin + paraloc^.shiftval := (sizeof(aint)-tcgsize2size[paraloc^.size])*(-8); + paraloc^.size := OS_INT; + end; + { ret in param? } if (vo_is_funcret in hp.varoptions) and is_abi_record(hp.vardef) then @@ -393,7 +404,7 @@ implementation begin TMIPSProcInfo(current_procinfo).register_used[0]:=true; TMIPSProcInfo(current_procinfo).register_name[0]:='result'; - TMIPSProcInfo(current_procinfo).register_size[0]:=paracgsize; + TMIPSProcInfo(current_procinfo).register_size[0]:=paraloc^.size; TMIPSProcInfo(current_procinfo).register_offset[0]:=0; end; //if (intparareg<>1) then @@ -453,7 +464,7 @@ implementation begin TMIPSProcInfo(current_procinfo).register_used[intparareg]:=true; TMIPSProcInfo(current_procinfo).register_name[intparareg]:=hp.prettyname; - TMIPSProcInfo(current_procinfo).register_size[intparareg]:=paracgsize; + TMIPSProcInfo(current_procinfo).register_size[intparareg]:=paraloc^.size; TMIPSProcInfo(current_procinfo).register_offset[intparareg]:=intparareg*mips_sizeof_register_param; end; if side=callerside then @@ -481,14 +492,18 @@ implementation else begin paraloc^.loc:=LOC_REFERENCE; + paraloc^.size:=int_cgsize(paralen); + { Force size to multiple of 4 for records passed by value, to obtain correct memory layout for big endian } +(* if (paradef.typ = recorddef) and (tcgsize2size[paraloc^.size] < tcgsize2size[OS_32]) then begin inc(paralen,tcgsize2size[OS_32]-tcgsize2size[paraloc^.size]); paraloc^.size := OS_32; end; +*) if side=callerside then begin paraloc^.reference.index := NR_STACK_POINTER_REG; @@ -506,7 +521,8 @@ implementation end; paraloc^.reference.offset:=intparasize; end; - inc(intparasize,align(tcgsize2size[paraloc^.size],mips_sizeof_register_param)); + inc(intparasize,align(paralen,mips_sizeof_register_param)); + paralen:=0; end; dec(paralen,tcgsize2size[paraloc^.size]); end;