* fixed some alignment trouble

This commit is contained in:
florian 2004-12-18 15:48:06 +00:00
parent c279c13d17
commit b44f17099c
2 changed files with 169 additions and 92 deletions

View File

@ -594,8 +594,9 @@ implementation
{$warning HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler} {$warning HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
{ Use unaligned copy when the offset is not aligned } { Use unaligned copy when the offset is not aligned }
len:=left.resulttype.def.size; len:=left.resulttype.def.size;
if (right.location.reference.offset mod sizeof(aint)<>0) and if ((right.location.reference.offset mod sizeof(aint)<>0) or
(len>sizeof(aint)) then (left.location.reference.offset mod sizeof(aint)<>0)) and
(len>=sizeof(aint)) then
cg.g_concatcopy_unaligned(exprasmlist,right.location.reference,left.location.reference,len) cg.g_concatcopy_unaligned(exprasmlist,right.location.reference,left.location.reference,len)
else else
cg.g_concatcopy(exprasmlist,right.location.reference,left.location.reference,len); cg.g_concatcopy(exprasmlist,right.location.reference,left.location.reference,len);
@ -952,7 +953,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.133 2004-11-29 17:32:56 peter Revision 1.134 2004-12-18 15:48:27 florian
* fixed some alignment trouble
Revision 1.133 2004/11/29 17:32:56 peter
* prevent some IEs with delphi methodpointers * prevent some IEs with delphi methodpointers
Revision 1.132 2004/11/09 17:26:47 peter Revision 1.132 2004/11/09 17:26:47 peter

View File

@ -88,6 +88,7 @@ interface
procedure g_save_standard_registers(list : taasmoutput);override; procedure g_save_standard_registers(list : taasmoutput);override;
procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);override; procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);override;
procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);override; procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);override;
procedure g_concatcopy_move(list : taasmoutput;const source,dest : treference;len : aint);
end; end;
TCg64Sparc=class(tcg64f32) TCg64Sparc=class(tcg64f32)
@ -975,6 +976,36 @@ implementation
{ ************* concatcopy ************ } { ************* concatcopy ************ }
procedure tcgsparc.g_concatcopy_move(list : taasmoutput;const source,dest : treference;len : aint);
var
paraloc1,paraloc2,paraloc3 : TCGPara;
begin
paraloc1.init;
paraloc2.init;
paraloc3.init;
paramanager.getintparaloc(pocall_default,1,paraloc1);
paramanager.getintparaloc(pocall_default,2,paraloc2);
paramanager.getintparaloc(pocall_default,3,paraloc3);
paramanager.allocparaloc(list,paraloc3);
a_param_const(list,OS_INT,len,paraloc3);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,dest,paraloc2);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,source,paraloc1);
paramanager.freeparaloc(list,paraloc3);
paramanager.freeparaloc(list,paraloc2);
paramanager.freeparaloc(list,paraloc1);
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
a_call_name(list,'FPC_MOVE');
dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
paraloc3.done;
paraloc2.done;
paraloc1.done;
end;
procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aint); procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aint);
var var
tmpreg1, tmpreg1,
@ -986,6 +1017,11 @@ implementation
begin begin
if len>high(longint) then if len>high(longint) then
internalerror(2002072704); internalerror(2002072704);
{ anybody wants to determine a good value here :)? }
if len>100 then
g_concatcopy_move(list,source,dest,len)
else
begin
reference_reset(src); reference_reset(src);
reference_reset(dst); reference_reset(dst);
{ load the address of source into src.base } { load the address of source into src.base }
@ -1060,36 +1096,70 @@ implementation
a_load_reg_ref(list,OS_8,OS_8,hreg,dst); a_load_reg_ref(list,OS_8,OS_8,hreg,dst);
end; end;
end; end;
end;
procedure tcgsparc.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint); procedure tcgsparc.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);
var var
paraloc1,paraloc2,paraloc3 : TCGPara; src, dst: TReference;
tmpreg1,
countreg: TRegister;
i : aint;
lab: tasmlabel;
begin begin
paraloc1.init; if len>31 then
paraloc2.init; g_concatcopy_move(list,source,dest,len)
paraloc3.init; else
paramanager.getintparaloc(pocall_default,1,paraloc1); begin
paramanager.getintparaloc(pocall_default,2,paraloc2); reference_reset(src);
paramanager.getintparaloc(pocall_default,3,paraloc3); reference_reset(dst);
paramanager.allocparaloc(list,paraloc3); { load the address of source into src.base }
a_param_const(list,OS_INT,len,paraloc3); src.base:=GetAddressRegister(list);
paramanager.allocparaloc(list,paraloc2); a_loadaddr_ref_reg(list,source,src.base);
a_paramaddr_ref(list,dest,paraloc2); { load the address of dest into dst.base }
paramanager.allocparaloc(list,paraloc2); dst.base:=GetAddressRegister(list);
a_paramaddr_ref(list,source,paraloc1); a_loadaddr_ref_reg(list,dest,dst.base);
paramanager.freeparaloc(list,paraloc3); { generate a loop }
paramanager.freeparaloc(list,paraloc2); if len>4 then
paramanager.freeparaloc(list,paraloc1); begin
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); { the offsets are zero after the a_loadaddress_ref_reg and just }
alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default)); { have to be set to 8. I put an Inc there so debugging may be }
a_call_name(list,'FPC_MOVE'); { easier (should offset be different from zero here, it will be }
dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default)); { easy to notice in the generated assembler }
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); countreg:=GetIntRegister(list,OS_INT);
paraloc3.done; tmpreg1:=GetIntRegister(list,OS_INT);
paraloc2.done; a_load_const_reg(list,OS_INT,len,countreg);
paraloc1.done; { explicitely allocate R_O0 since it can be used safely here }
{ (for holding date that's being copied) }
objectlibrary.getlabel(lab);
a_label(list, lab);
list.concat(taicpu.op_ref_reg(A_LDUB,src,tmpreg1));
list.concat(taicpu.op_reg_ref(A_STB,tmpreg1,dst));
list.concat(taicpu.op_reg_const_reg(A_ADD,src.base,1,src.base));
list.concat(taicpu.op_reg_const_reg(A_ADD,dst.base,1,dst.base));
list.concat(taicpu.op_reg_const_reg(A_SUBcc,countreg,1,countreg));
a_jmp_cond(list,OC_NE,lab);
list.concat(taicpu.op_none(A_NOP));
{ keep the registers alive }
list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
list.concat(taicpu.op_reg_reg(A_MOV,src.base,src.base));
list.concat(taicpu.op_reg_reg(A_MOV,dst.base,dst.base));
end
else
begin
{ unrolled loop }
tmpreg1:=GetIntRegister(list,OS_INT);
for i:=1 to len do
begin
list.concat(taicpu.op_ref_reg(A_LDUB,src,tmpreg1));
list.concat(taicpu.op_reg_ref(A_STB,tmpreg1,dst));
inc(src.offset);
inc(dst.offset);
end; end;
end;
end;
end;
{**************************************************************************** {****************************************************************************
TCG64Sparc TCG64Sparc
@ -1245,7 +1315,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.98 2004-10-31 21:45:03 peter Revision 1.99 2004-12-18 15:48:06 florian
* fixed some alignment trouble
Revision 1.98 2004/10/31 21:45:03 peter
* generic tlocation * generic tlocation
* move tlocation to cgutils * move tlocation to cgutils