* support for unaligned loads/stores on sparc

git-svn-id: trunk@7062 -
This commit is contained in:
florian 2007-04-05 12:49:12 +00:00
parent b54185401c
commit 9140766d5a
2 changed files with 42 additions and 31 deletions

View File

@ -1152,12 +1152,12 @@ implementation
begin
intloadsize := packedbitsloadsize(sref.bitlen);
{$if not defined(arm)}
{$if not(defined(arm)) and not(defined(sparc))}
{ may need to be split into several smaller loads/stores }
if (tf_requires_proper_alignment in target_info.flags) and
(intloadsize <> sref.ref.alignment) then
internalerror(2006082011);
{$endif not defined(arm)}
{$endif not(defined(arm)) and not(defined(sparc))}
if (intloadsize = 0) then
internalerror(2006081310);
@ -1794,24 +1794,26 @@ implementation
if ref.alignment<>0 then
begin
tmpref:=ref;
{ we take care of the alignment now }
tmpref.alignment:=0;
case FromSize of
OS_16,OS_S16:
begin
if target_info.endian=endian_big then
inc(tmpref.offset);
a_load_reg_ref(list,OS_8,OS_8,register,Ref);
a_load_reg_ref(list,OS_8,OS_8,register,tmpref);
a_op_const_reg(list,OP_SHR,OS_8,8,register);
if target_info.endian=endian_big then
dec(tmpref.offset)
else
inc(tmpref.offset);
a_load_reg_ref(list,OS_8,OS_8,register,Ref);
a_load_reg_ref(list,OS_8,OS_8,register,tmpref);
end;
OS_32,OS_S32:
begin
if target_info.endian=endian_big then
inc(tmpref.offset,3);
a_load_reg_ref(list,OS_8,OS_8,register,Ref);
a_load_reg_ref(list,OS_8,OS_8,register,tmpref);
for i:=1 to 3 do
begin
a_op_const_reg(list,OP_SHR,OS_8,8,register);
@ -1819,11 +1821,11 @@ implementation
dec(tmpref.offset)
else
inc(tmpref.offset);
a_load_reg_ref(list,OS_8,OS_8,register,Ref);
a_load_reg_ref(list,OS_8,OS_8,register,tmpref);
end;
end
else
a_load_reg_ref(list,fromsize,tosize,register,ref);
a_load_reg_ref(list,fromsize,tosize,register,tmpref);
end;
end
else
@ -1840,26 +1842,28 @@ implementation
if ref.alignment<>0 then
begin
tmpref:=ref;
{ we take care of the alignment now }
tmpref.alignment:=0;
case FromSize of
OS_16,OS_S16:
begin
if target_info.endian=endian_little then
inc(tmpref.offset);
a_load_ref_reg(list,OS_8,OS_8,Ref,register);
a_load_ref_reg(list,OS_8,OS_8,tmpref,register);
a_op_const_reg(list,OP_SHL,OS_8,8,register);
if target_info.endian=endian_little then
dec(tmpref.offset)
else
inc(tmpref.offset);
tmpreg:=getintregister(list,OS_INT);
a_load_ref_reg(list,OS_8,OS_16,Ref,tmpreg);
a_load_ref_reg(list,OS_8,OS_16,tmpref,tmpreg);
a_op_reg_reg(list,OP_OR,OS_16,tmpreg,register);
end;
OS_32,OS_S32:
begin
if target_info.endian=endian_little then
inc(tmpref.offset,3);
a_load_ref_reg(list,OS_8,OS_8,Ref,register);
a_load_ref_reg(list,OS_8,OS_8,tmpref,register);
for i:=1 to 3 do
begin
a_op_const_reg(list,OP_SHL,OS_8,8,register);
@ -1868,12 +1872,12 @@ implementation
else
inc(tmpref.offset);
tmpreg:=getintregister(list,OS_INT);
a_load_ref_reg(list,OS_8,OS_32,Ref,tmpreg);
a_load_ref_reg(list,OS_8,OS_32,tmpref,tmpreg);
a_op_reg_reg(list,OP_OR,OS_32,tmpreg,register);
end;
end
else
a_load_ref_reg(list,fromsize,tosize,ref,register);
a_load_ref_reg(list,fromsize,tosize,tmpref,register);
end;
end
else

View File

@ -505,25 +505,32 @@ implementation
begin
if (TCGSize2Size[fromsize] >= TCGSize2Size[tosize]) then
fromsize := tosize;
case fromsize of
OS_S8:
Op:=A_LDSB;{Load Signed Byte}
OS_8:
Op:=A_LDUB;{Load Unsigned Byte}
OS_S16:
Op:=A_LDSH;{Load Signed Halfword}
OS_16:
Op:=A_LDUH;{Load Unsigned Halfword}
OS_S32,
OS_32:
Op:=A_LD;{Load Word}
OS_S64,
OS_64:
Op:=A_LDD;{Load a Long Word}
else
InternalError(2002122101);
end;
handle_load_store(list,false,op,reg,ref);
if Ref.alignment<>0 then
begin
a_load_ref_reg_unaligned(list,FromSize,ToSize,ref,reg);
end
else
begin
case fromsize of
OS_S8:
Op:=A_LDSB;{Load Signed Byte}
OS_8:
Op:=A_LDUB;{Load Unsigned Byte}
OS_S16:
Op:=A_LDSH;{Load Signed Halfword}
OS_16:
Op:=A_LDUH;{Load Unsigned Halfword}
OS_S32,
OS_32:
Op:=A_LD;{Load Word}
OS_S64,
OS_64:
Op:=A_LDD;{Load a Long Word}
else
InternalError(2002122101);
end;
handle_load_store(list,false,op,reg,ref);
end;
end;