* several arm fixes

git-svn-id: trunk@4742 -
This commit is contained in:
florian 2006-09-27 21:05:05 +00:00
parent 506f44dc7a
commit 67ba76f090
5 changed files with 66 additions and 49 deletions

View File

@ -394,7 +394,7 @@ unit cgcpu;
OP_SHL:
begin
if a>32 then
internalerror(200308291);
internalerror(200308294);
if a<>0 then
begin
shifterop_reset(so);
@ -422,7 +422,7 @@ unit cgcpu;
OP_SAR:
begin
if a>32 then
internalerror(200308291);
internalerror(200308295);
if a<>0 then
begin
shifterop_reset(so);
@ -465,7 +465,7 @@ unit cgcpu;
else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a-1,l1) and not(cgsetflags or setflags) then
begin
if l1>32 then{roozbeh does this ever happen?}
internalerror(200308291);
internalerror(200308296);
shifterop_reset(so);
so.shiftmode:=SM_LSL;
so.shiftimm:=l1;
@ -844,7 +844,7 @@ unit cgcpu;
OS_S32:
oppostfix:=PF_None;
else
InternalError(200308291);
InternalError(200308297);
end;
if Ref.alignment<>0 then
begin
@ -1020,7 +1020,15 @@ unit cgcpu;
LOC_FPUREGISTER,LOC_CFPUREGISTER:
a_loadfpu_ref_reg(list,size,ref,hloc^.register);
LOC_REGISTER :
a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
case hloc^.size of
OS_F32:
a_load_ref_reg(list,OS_32,OS_32,href,hloc^.register);
OS_64,
OS_F64:
cg64.a_param64_ref(list,href,paraloc);
else
a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
end;
LOC_REFERENCE :
begin
reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
@ -1046,8 +1054,10 @@ unit cgcpu;
oppostfix:toppostfix;
begin
case size of
OS_32,
OS_F32:
oppostfix:=PF_S;
OS_64,
OS_F64:
oppostfix:=PF_D;
OS_F80:

View File

@ -288,7 +288,7 @@ unit cpupara;
OS_F32:
paraloc^.size:=OS_32;
OS_F64:
paraloc^.size:=OS_64;
paraloc^.size:=OS_32;
else
internalerror(2005082901);
end

View File

@ -1047,18 +1047,18 @@ implementation
in memory. They are like a regular reference, but contain an extra bit
offset (either constant -startbit- or variable -bitindexreg, always OS_INT)
and a bit length (always constant).
Bit packed values are stored differently in memory depending on whether we
are on a big or a little endian system (compatible with at least GPC). The
size of the basic working unit is always the smallest power-of-2 byte size
which can contain the bit value (so 1..8 bits -> 1 byte, 9..16 bits -> 2
bytes, 17..32 bits -> 4 bytes etc).
On a big endian, 5-bit: values are stored like this:
11111222 22333334 44445555 56666677 77788888
The leftmost bit of each 5-bit value corresponds to the most significant
bit.
On little endian, it goes like this:
22211111 43333322 55554444 77666665 88888777
In this case, per byte the left-most bit is more significant than those on
@ -1066,10 +1066,10 @@ implementation
those in the previous byte (e.g., the 222 in the first byte are the low
three bits of that value, while the 22 in the second byte are the upper
three bits.
Big endian, 9 bit values:
11111111 12222222 22333333 33344444 ...
Little endian, 9 bit values:
11111111 22222221 33333322 44444333 ...
This is memory representation and the 16 bit values are byteswapped.
@ -1080,7 +1080,7 @@ implementation
alignment can be guaranteed), this becomes:
22222221 11111111 44444333 33333322 ...
(l)ow u l l u l u
The startbit/bitindex in a subsetreference always refers to
a) on big endian: the most significant bit of the value
(bits counted from left to right, both memory an registers)
@ -1101,13 +1101,13 @@ implementation
intloadsize: aint;
begin
intloadsize := packedbitsloadsize(sref.bitlen);
{$ifdef cpurequiresproperalignment}
{ may need to be split into several smaller loads/stores }
if intloadsize <> sref.ref.alignment then
internalerror(2006082011);
{$endif cpurequiresproperalignment}
if (intloadsize = 0) then
internalerror(2006081310);
@ -1205,7 +1205,7 @@ implementation
a_op_const_reg(list,OP_SUB,OS_INT,1,tmpreg);
{ if (tmpreg = cpu_bit_size) then extra_value_reg := 0 }
a_op_reg_reg(list,OP_AND,OS_INT,tmpreg,extra_value_reg);
end;
end;
{$endif x86}
{ merge }
a_op_reg_reg(list,OP_OR,OS_INT,extra_value_reg,valuereg);
@ -1301,7 +1301,7 @@ implementation
destreg := makeregsize(list,destreg,tosize);
end
end;
procedure tcg.a_load_reg_subsetref(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sref: tsubsetreference);
var
@ -1315,7 +1315,7 @@ implementation
{ the register must be able to contain the requested value }
if (tcgsize2size[fromsize]*8 < sref.bitlen) then
internalerror(2006081613);
get_subsetref_load_info(sref,loadsize,extra_load);
loadbitsize := tcgsize2size[loadsize]*8;
@ -1418,7 +1418,7 @@ implementation
a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
valuereg := makeregsize(list,valuereg,loadsize);
a_load_reg_ref(list,loadsize,loadsize,valuereg,sref.ref);
{ transfer second part }
if (target_info.endian = endian_big) then
begin
@ -1470,7 +1470,7 @@ implementation
a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
a_op_reg_reg(list,OP_AND,OS_INT,maskreg,valuereg);
{ insert the value }
tmpreg := getintregister(list,OS_INT);
a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg);
@ -1527,13 +1527,13 @@ implementation
{ if (tmpreg = cpu_bit_size) then tmpreg := maskreg := 0 }
a_op_reg_reg(list,OP_AND,OS_INT,valuereg,tmpreg);
a_op_reg_reg(list,OP_AND,OS_INT,valuereg,maskreg);
end;
end;
{$endif x86}
end;
a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
a_op_reg_reg(list,OP_AND,OS_INT,maskreg,extra_value_reg);
if (target_info.endian = endian_big) then
a_op_reg_reg(list,OP_SHL,OS_INT,tmpindexreg,tmpreg)
else
@ -1614,7 +1614,7 @@ implementation
a_load_subsetref_reg(list,fromsubsetsize,tosubsetsize,fromsref,tmpreg);
a_load_reg_subsetreg(list,tosubsetsize,tosubsetsize,tmpreg,tosreg);
end;
procedure tcg.a_load_subsetreg_subsetref(list: TAsmlist; fromsubsetsize, tosubsetsize : tcgsize; const fromsreg: tsubsetregister; const tosref: tsubsetreference);
var

View File

@ -76,6 +76,7 @@ implementation
uses
systems,
cutils,verbose,globals,
cpuinfo,
symconst,symtable,defutil,paramgr,
cgbase,pass_2,
aasmbase,aasmtai,aasmdata,
@ -575,32 +576,38 @@ implementation
location_reset(location,LOC_REGISTER,cgsize);
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
begin
retloc:=procdefinition.funcretloc[callerside];
if retloc.loc<>LOC_REGISTER then
internalerror(200409141);
{ the function result registers are already allocated }
if getsupreg(retloc.register64.reglo)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reglo);
location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reglo,location.register64.reglo);
if getsupreg(retloc.register64.reghi)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reghi);
location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reghi,location.register64.reghi);
end
begin
retloc:=procdefinition.funcretloc[callerside];
if retloc.loc<>LOC_REGISTER then
internalerror(200409141);
{ the function result registers are already allocated }
if getsupreg(retloc.register64.reglo)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reglo);
location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reglo,location.register64.reglo);
if getsupreg(retloc.register64.reghi)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reghi);
location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reghi,location.register64.reghi);
end
else
{$endif cpu64bit}
begin
{ change register size after the unget because the
getregister was done for the full register
def_cgsize(resulttype.def) is used here because
it could be a constructor call }
if getsupreg(procdefinition.funcretloc[callerside].register)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,procdefinition.funcretloc[callerside].register);
location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resulttype.def));
cg.a_load_reg_reg(current_asmdata.CurrAsmList,cgsize,def_cgsize(resulttype.def),procdefinition.funcretloc[callerside].register,location.register);
end;
begin
{ change register size after the unget because the
getregister was done for the full register
def_cgsize(resulttype.def) is used here because
it could be a constructor call }
if getsupreg(procdefinition.funcretloc[callerside].register)<first_int_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,procdefinition.funcretloc[callerside].register);
location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resulttype.def));
cg.a_load_reg_reg(current_asmdata.CurrAsmList,cgsize,def_cgsize(resulttype.def),procdefinition.funcretloc[callerside].register,location.register);
end;
{$ifdef arm}
if (resulttype.def.deftype=floatdef) and (aktfputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) then
begin
location_force_mem(current_asmdata.CurrAsmList,location);
end;
{$endif arm}
end
else
begin

View File

@ -1578,7 +1578,7 @@ implementation
paraloc : pcgparalocation;
href : treference;
sizeleft : aint;
{$ifdef sparc}
{$if defined(sparc) or defined(arm)}
tempref : treference;
{$endif sparc}
begin
@ -1696,8 +1696,8 @@ implementation
end;
LOC_CFPUREGISTER :
begin
{$ifdef sparc}
{ Sparc passes floats in int registers, when loading to fpu register
{$if defined(sparc) or defined(arm)}
{ 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);