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

View File

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

View File

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

View File

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

View File

@ -1578,7 +1578,7 @@ implementation
paraloc : pcgparalocation; paraloc : pcgparalocation;
href : treference; href : treference;
sizeleft : aint; sizeleft : aint;
{$ifdef sparc} {$if defined(sparc) or defined(arm)}
tempref : treference; tempref : treference;
{$endif sparc} {$endif sparc}
begin begin
@ -1696,8 +1696,8 @@ implementation
end; end;
LOC_CFPUREGISTER : LOC_CFPUREGISTER :
begin begin
{$ifdef sparc} {$if defined(sparc) or defined(arm)}
{ Sparc passes floats in int registers, when loading to fpu register { Arm and Sparc passes floats in int registers, when loading to fpu register
we need a temp } we need a temp }
sizeleft := TCGSize2Size[currpara.initialloc.size]; sizeleft := TCGSize2Size[currpara.initialloc.size];
tg.GetTemp(list,sizeleft,tt_normal,tempref); tg.GetTemp(list,sizeleft,tt_normal,tempref);