diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas index dfcc9ea419..85e7fe8619 100644 --- a/compiler/hlcgobj.pas +++ b/compiler/hlcgobj.pas @@ -107,6 +107,21 @@ unit hlcgobj; result loading, this is the register type used } function def2regtyp(def: tdef): tregistertype; virtual; + {# Returns a reference with its base address set from a pointer that + has been loaded in a register. + + A generic version is provided. This routine should be overridden + on platforms which support pointers with different sizes (for + example i8086 near and far pointers) or require some other sort of + special consideration when converting a pointer in a register to a + reference. + + @param(ref where the result is returned) + @param(regsize the type of the pointer, contained in the reg parameter) + @param(reg register containing the value of a pointer) + } + procedure reference_reset_base(var ref: treference; regsize: tdef; reg: tregister; offset, alignment: longint); virtual; + {# Emit a label to the instruction stream. } procedure a_label(list : TAsmList;l : tasmlabel); inline; @@ -727,6 +742,14 @@ implementation end; end; + procedure thlcgobj.reference_reset_base(var ref: treference; regsize: tdef; + reg: tregister; offset, alignment: longint); + begin + reference_reset(ref,alignment); + ref.base:=reg; + ref.offset:=offset; + end; + procedure thlcgobj.a_label(list: TAsmList; l: tasmlabel); inline; begin cg.a_label(list,l); @@ -765,7 +788,7 @@ implementation a_load_reg_reg(list,size,cgpara.location^.def,r,cgpara.location^.register); LOC_REFERENCE,LOC_CREFERENCE: begin - reference_reset_base(ref,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(ref,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); a_load_reg_ref(list,size,cgpara.location^.def,r,ref); end; LOC_MMREGISTER,LOC_CMMREGISTER: @@ -795,7 +818,7 @@ implementation a_load_const_reg(list,cgpara.location^.def,a,cgpara.location^.register); LOC_REFERENCE,LOC_CREFERENCE: begin - reference_reset_base(ref,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(ref,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); a_load_const_ref(list,cgpara.location^.def,a,ref); end else @@ -926,7 +949,7 @@ implementation begin if assigned(location^.next) then internalerror(2010052906); - reference_reset_base(ref,location^.reference.index,location^.reference.offset,newalignment(cgpara.alignment,cgpara.intsize-sizeleft)); + reference_reset_base(ref,voidstackpointertype,location^.reference.index,location^.reference.offset,newalignment(cgpara.alignment,cgpara.intsize-sizeleft)); if (def_cgsize(size)<>OS_NO) and (size.size=sizeleft) and (sizeleft<=sizeof(aint)) then @@ -2365,7 +2388,7 @@ implementation LOC_REFERENCE,LOC_CREFERENCE: begin cgpara.check_simple_location; - reference_reset_base(ref,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(ref,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); a_loadfpu_reg_ref(list,fromsize,cgpara.def,r,ref); end; LOC_REGISTER,LOC_CREGISTER: @@ -2396,7 +2419,7 @@ implementation LOC_REFERENCE,LOC_CREFERENCE: begin cgpara.check_simple_location; - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); { concatcopy should choose the best way to copy the data } g_concatcopy(list,fromsize,ref,href); end; @@ -2476,7 +2499,7 @@ implementation a_loadmm_reg_reg(list,fromsize,cgpara.def,reg,cgpara.location^.register,shuffle); LOC_REFERENCE,LOC_CREFERENCE: begin - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); a_loadmm_reg_ref(list,fromsize,cgpara.def,reg,href,shuffle); end; LOC_REGISTER,LOC_CREGISTER: @@ -3805,14 +3828,14 @@ implementation begin if not loadref then internalerror(200410231); - reference_reset_base(ref,l.register,0,alignment); + reference_reset_base(ref,voidpointertype,l.register,0,alignment); end; LOC_REFERENCE, LOC_CREFERENCE : begin if loadref then begin - reference_reset_base(ref,getaddressregister(list,voidpointertype),0,alignment); + reference_reset_base(ref,voidpointertype,getaddressregister(list,voidpointertype),0,alignment); { it's a pointer to def } a_load_ref_reg(list,voidpointertype,voidpointertype,l.reference,ref.base); end @@ -4305,7 +4328,7 @@ implementation if assigned(hp^.def) and is_managed_type(hp^.def) then begin - reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,current_procinfo.framepointer,hp^.pos,voidstackpointertype.size); g_initialize(list,hp^.def,href); end; hp:=hp^.next; @@ -4353,7 +4376,7 @@ implementation is_managed_type(hp^.def) then begin include(current_procinfo.flags,pi_needs_implicit_finally); - reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,current_procinfo.framepointer,hp^.pos,voidstackpointertype.size); g_finalize(list,hp^.def,href); end; hp:=hp^.next; @@ -4853,7 +4876,7 @@ implementation case para.location^.loc of LOC_REFERENCE,LOC_CREFERENCE: begin - reference_reset_base(href,para.location^.reference.index,para.location^.reference.offset,para.alignment); + reference_reset_base(href,voidstackpointertype,para.location^.reference.index,para.location^.reference.offset,para.alignment); a_load_ref_ref(list,para.def,para.def,href,destloc.reference); end; else diff --git a/compiler/i386/hlcgcpu.pas b/compiler/i386/hlcgcpu.pas index e6eaeadae3..e4372549c3 100644 --- a/compiler/i386/hlcgcpu.pas +++ b/compiler/i386/hlcgcpu.pas @@ -78,10 +78,10 @@ implementation (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then begin cg.g_stackpointer_alloc(list,stacksize); - reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size); end else - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.a_loadfpu_reg_ref(list,locsize,locsize,l.register,href); end; LOC_FPUREGISTER: @@ -123,10 +123,10 @@ implementation (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then begin cg.g_stackpointer_alloc(list,stacksize); - reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size); end else - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.a_loadmm_reg_ref(list,locsize,locsize,l.register,href,mms_movescalar); end; LOC_FPUREGISTER: @@ -152,7 +152,7 @@ implementation cg.a_load_ref_cgpara(list,locsize,l.reference,cgpara) else begin - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.g_concatcopy(list,l.reference,href,stacksize); end; end; diff --git a/compiler/i8086/hlcgcpu.pas b/compiler/i8086/hlcgcpu.pas index bed828edb1..ba217f79f3 100644 --- a/compiler/i8086/hlcgcpu.pas +++ b/compiler/i8086/hlcgcpu.pas @@ -37,12 +37,17 @@ interface type + + { thlcgcpu } + thlcgcpu = class(thlcgx86) protected procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override; public function getaddressregister(list:TAsmList;size:tdef):Tregister;override; + procedure reference_reset_base(var ref: treference; regsize: tdef; reg: tregister; offset, alignment: longint); override; + procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override; procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override; @@ -58,7 +63,8 @@ implementation paramgr, cpubase,cpuinfo,tgobj,cgobj,cgcpu, defutil, - symconst; + symconst, + procinfo; { thlcgcpu } @@ -85,10 +91,10 @@ implementation (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then begin cg.g_stackpointer_alloc(list,stacksize); - reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size); end else - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.a_loadfpu_reg_ref(list,locsize,locsize,l.register,href); end; LOC_FPUREGISTER: @@ -130,10 +136,10 @@ implementation (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then begin cg.g_stackpointer_alloc(list,stacksize); - reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint)); + reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size); end else - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.a_loadmm_reg_ref(list,locsize,locsize,l.register,href,mms_movescalar); end; LOC_FPUREGISTER: @@ -159,7 +165,7 @@ implementation cg.a_load_ref_cgpara(list,locsize,l.reference,cgpara) else begin - reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); + reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment); cg.g_concatcopy(list,l.reference,href,stacksize); end; end; @@ -186,6 +192,15 @@ implementation end; + procedure thlcgcpu.reference_reset_base(var ref: treference; regsize: tdef; + reg: tregister; offset, alignment: longint); + begin + inherited reference_reset_base(ref, regsize, reg, offset, alignment); + if is_farpointer(regsize) or is_hugepointer(regsize) then + ref.segment:=GetNextReg(reg); + end; + + procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); begin if paramanager.use_fixed_stack then diff --git a/compiler/jvm/hlcgcpu.pas b/compiler/jvm/hlcgcpu.pas index 64207acea6..9fad597137 100644 --- a/compiler/jvm/hlcgcpu.pas +++ b/compiler/jvm/hlcgcpu.pas @@ -1031,7 +1031,7 @@ implementation end; art_indexref: begin - reference_reset_base(href,ref.indexbase,ref.indexoffset,4); + cgutils.reference_reset_base(href,ref.indexbase,ref.indexoffset,4); href.symbol:=ref.indexsymbol; a_load_ref_stack(list,s32inttype,href,prepare_stack_for_ref(list,href,false)); end; @@ -1789,7 +1789,7 @@ implementation { passed by reference in array of single element; l contains the base address of the array } location_reset_ref(tmploc,LOC_REFERENCE,OS_ADDR,4); - reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,4); + cgutils.reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,4); tmploc.reference.arrayreftype:=art_indexconst; tmploc.reference.indexoffset:=0; a_load_loc_reg(list,java_jlobject,java_jlobject,l,tmploc.reference.base); @@ -1856,7 +1856,7 @@ implementation case current_procinfo.procdef.proctypeoption of potype_unitinit: begin - reference_reset_base(ref,NR_NO,0,1); + cgutils.reference_reset_base(ref,NR_NO,0,1); if assigned(current_module.globalsymtable) then allocate_implicit_structs_for_st_with_base_ref(list,current_module.globalsymtable,ref,staticvarsym); allocate_implicit_structs_for_st_with_base_ref(list,current_module.localsymtable,ref,staticvarsym); @@ -1866,7 +1866,7 @@ implementation { also initialise local variables, if any } inherited; { initialise class fields } - reference_reset_base(ref,NR_NO,0,1); + cgutils.reference_reset_base(ref,NR_NO,0,1); allocate_implicit_structs_for_st_with_base_ref(list,tabstractrecorddef(current_procinfo.procdef.owner.defowner).symtable,ref,staticvarsym); end else @@ -2415,7 +2415,7 @@ implementation internalerror(2011033001); selfreg:=getaddressregister(list,selfpara.vardef); a_load_loc_reg(list,obj,obj,selfpara.localloc,selfreg); - reference_reset_base(ref,selfreg,0,1); + cgutils.reference_reset_base(ref,selfreg,0,1); allocate_implicit_structs_for_st_with_base_ref(list,obj.symtable,ref,fieldvarsym); end;