mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 21:09:24 +02:00
* several arm fixes
git-svn-id: trunk@4742 -
This commit is contained in:
parent
506f44dc7a
commit
67ba76f090
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user