mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-29 16:20:55 +02:00
Fix ARMv3/ARMv2A support.
git-svn-id: trunk@31561 -
This commit is contained in:
parent
44ad5af04d
commit
dac294c680
@ -378,7 +378,14 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
InternalError(200308297);
|
InternalError(200308297);
|
||||||
end;
|
end;
|
||||||
if (ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[fromsize]) then
|
|
||||||
|
if (fromsize=OS_S8) and
|
||||||
|
(not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
|
||||||
|
oppostfix:=PF_B;
|
||||||
|
|
||||||
|
if ((ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[fromsize])) or
|
||||||
|
((not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) and
|
||||||
|
(oppostfix in [PF_SH,PF_H])) then
|
||||||
begin
|
begin
|
||||||
if target_info.endian=endian_big then
|
if target_info.endian=endian_big then
|
||||||
dir:=-1
|
dir:=-1
|
||||||
@ -479,7 +486,10 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||||
|
|
||||||
if (fromsize=OS_S8) and (tosize = OS_16) then
|
if (fromsize=OS_S8) and
|
||||||
|
(not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
|
||||||
|
a_load_reg_reg(list,OS_S8,OS_32,reg,reg)
|
||||||
|
else if (fromsize=OS_S8) and (tosize = OS_16) then
|
||||||
a_load_reg_reg(list,OS_16,OS_32,reg,reg);
|
a_load_reg_reg(list,OS_16,OS_32,reg,reg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1116,7 +1126,8 @@ unit cgcpu;
|
|||||||
OP_IMUL,
|
OP_IMUL,
|
||||||
OP_MUL:
|
OP_MUL:
|
||||||
begin
|
begin
|
||||||
if cgsetflags or setflags then
|
if (cgsetflags or setflags) and
|
||||||
|
(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
|
||||||
begin
|
begin
|
||||||
overflowreg:=getintregister(list,size);
|
overflowreg:=getintregister(list,size);
|
||||||
if op=OP_IMUL then
|
if op=OP_IMUL then
|
||||||
@ -1183,6 +1194,8 @@ unit cgcpu;
|
|||||||
procedure tcgarm.a_mul_reg_reg_pair(list: tasmlist; size: tcgsize; src1,src2,dstlo,dsthi: tregister);
|
procedure tcgarm.a_mul_reg_reg_pair(list: tasmlist; size: tcgsize; src1,src2,dstlo,dsthi: tregister);
|
||||||
var
|
var
|
||||||
asmop: tasmop;
|
asmop: tasmop;
|
||||||
|
begin
|
||||||
|
if CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype] then
|
||||||
begin
|
begin
|
||||||
list.concat(tai_comment.create(strpnew('tcgarm.a_mul_reg_reg_pair called')));
|
list.concat(tai_comment.create(strpnew('tcgarm.a_mul_reg_reg_pair called')));
|
||||||
case size of
|
case size of
|
||||||
@ -1199,6 +1212,17 @@ unit cgcpu;
|
|||||||
if (dsthi = NR_NO) then
|
if (dsthi = NR_NO) then
|
||||||
dsthi:=getintregister(list,size);
|
dsthi:=getintregister(list,size);
|
||||||
list.concat(taicpu.op_reg_reg_reg_reg(asmop, dstlo, dsthi, src1,src2));
|
list.concat(taicpu.op_reg_reg_reg_reg(asmop, dstlo, dsthi, src1,src2));
|
||||||
|
end
|
||||||
|
else if dsthi=NR_NO then
|
||||||
|
begin
|
||||||
|
if (dstlo = NR_NO) then
|
||||||
|
dstlo:=getintregister(list,size);
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_MUL, dstlo, src1,src2));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
internalerror(2015083022);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tbasecgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
function tbasecgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
||||||
@ -1373,7 +1397,10 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
InternalError(200308299);
|
InternalError(200308299);
|
||||||
end;
|
end;
|
||||||
if (ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[tosize]) then
|
|
||||||
|
if ((ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[tosize])) or
|
||||||
|
((not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) and
|
||||||
|
(oppostfix =PF_H)) then
|
||||||
begin
|
begin
|
||||||
if target_info.endian=endian_big then
|
if target_info.endian=endian_big then
|
||||||
dir:=-1
|
dir:=-1
|
||||||
@ -1432,6 +1459,8 @@ unit cgcpu;
|
|||||||
function tbasecgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
function tbasecgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
||||||
var
|
var
|
||||||
oppostfix:toppostfix;
|
oppostfix:toppostfix;
|
||||||
|
href: treference;
|
||||||
|
tmpreg: TRegister;
|
||||||
begin
|
begin
|
||||||
case ToSize of
|
case ToSize of
|
||||||
{ signed integer registers }
|
{ signed integer registers }
|
||||||
@ -1447,6 +1476,21 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
InternalError(2003082910);
|
InternalError(2003082910);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if (tosize in [OS_S16,OS_16]) and
|
||||||
|
(not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
|
||||||
|
begin
|
||||||
|
result:=handle_load_store(list,A_STR,PF_B,reg,ref);
|
||||||
|
|
||||||
|
tmpreg:=getintregister(list,OS_INT);
|
||||||
|
a_op_const_reg_reg(list,OP_SHR,OS_INT,8,reg,tmpreg);
|
||||||
|
|
||||||
|
href:=result;
|
||||||
|
inc(href.offset);
|
||||||
|
|
||||||
|
handle_load_store(list,A_STR,PF_B,tmpreg,href);
|
||||||
|
end
|
||||||
|
else
|
||||||
result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
|
result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1454,6 +1498,9 @@ unit cgcpu;
|
|||||||
function tbasecgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
function tbasecgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
||||||
var
|
var
|
||||||
oppostfix:toppostfix;
|
oppostfix:toppostfix;
|
||||||
|
so: tshifterop;
|
||||||
|
tmpreg: TRegister;
|
||||||
|
href: treference;
|
||||||
begin
|
begin
|
||||||
case FromSize of
|
case FromSize of
|
||||||
{ signed integer registers }
|
{ signed integer registers }
|
||||||
@ -1471,6 +1518,32 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
InternalError(200308291);
|
InternalError(200308291);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if (tosize=OS_S8) and
|
||||||
|
(not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
|
||||||
|
begin
|
||||||
|
result:=handle_load_store(list,A_LDR,PF_B,reg,ref);
|
||||||
|
a_load_reg_reg(list,OS_S8,OS_32,reg,reg);
|
||||||
|
end
|
||||||
|
else if (tosize in [OS_S16,OS_16]) and
|
||||||
|
(not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
|
||||||
|
begin
|
||||||
|
result:=handle_load_store(list,A_LDR,PF_B,reg,ref);
|
||||||
|
|
||||||
|
tmpreg:=getintregister(list,OS_INT);
|
||||||
|
|
||||||
|
href:=result;
|
||||||
|
inc(href.offset);
|
||||||
|
|
||||||
|
handle_load_store(list,A_LDR,PF_B,tmpreg,href);
|
||||||
|
|
||||||
|
shifterop_reset(so);
|
||||||
|
so.shiftmode:=SM_LSL;
|
||||||
|
so.shiftimm:=8;
|
||||||
|
|
||||||
|
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,reg,tmpreg,so));
|
||||||
|
end
|
||||||
|
else
|
||||||
result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -765,7 +765,8 @@ Const
|
|||||||
|
|
||||||
type
|
type
|
||||||
tcpuflags =
|
tcpuflags =
|
||||||
(CPUARM_HAS_BX, { CPU supports the BX instruction }
|
(CPUARM_HAS_ALL_MEM, { CPU supports LDRSB/LDRSH/LDRH/STRH instructions }
|
||||||
|
CPUARM_HAS_BX, { CPU supports the BX instruction }
|
||||||
CPUARM_HAS_BLX, { CPU supports the BLX rX instruction }
|
CPUARM_HAS_BLX, { CPU supports the BLX rX instruction }
|
||||||
CPUARM_HAS_BLX_LABEL, { CPU supports the BLX <label> instruction }
|
CPUARM_HAS_BLX_LABEL, { CPU supports the BLX <label> instruction }
|
||||||
CPUARM_HAS_CLZ, { CPU supports the CLZ instruction }
|
CPUARM_HAS_CLZ, { CPU supports the CLZ instruction }
|
||||||
@ -784,23 +785,23 @@ Const
|
|||||||
cpu_capabilities : array[tcputype] of set of tcpuflags =
|
cpu_capabilities : array[tcputype] of set of tcpuflags =
|
||||||
( { cpu_none } [],
|
( { cpu_none } [],
|
||||||
{ cpu_armv3 } [],
|
{ cpu_armv3 } [],
|
||||||
{ cpu_armv4 } [CPUARM_HAS_UMULL],
|
{ cpu_armv4 } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv4t } [CPUARM_HAS_BX,CPUARM_HAS_UMULL],
|
{ cpu_armv4t } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv5 } [CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
|
{ cpu_armv5 } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv5t } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
|
{ cpu_armv5t } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv5te } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
|
{ cpu_armv5te } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv5tej } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
|
{ cpu_armv5tej } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv6 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
{ cpu_armv6 } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv6k } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
{ cpu_armv6k } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv6t2 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
{ cpu_armv6t2 } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv6z } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
{ cpu_armv6z } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv6m } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
|
{ cpu_armv6m } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
|
||||||
{ the identifier armv7 is should not be used, it is considered being equal to armv7a }
|
{ the identifier armv7 is should not be used, it is considered being equal to armv7a }
|
||||||
{ cpu_armv7 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
{ cpu_armv7 } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv7a } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
{ cpu_armv7a } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv7r } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
{ cpu_armv7r } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv7m } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
{ cpu_armv7m } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
|
||||||
{ cpu_armv7em } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
|
{ cpu_armv7em } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
|
||||||
);
|
);
|
||||||
|
|
||||||
{ contains all CPU supporting any kind of thumb instruction set }
|
{ contains all CPU supporting any kind of thumb instruction set }
|
||||||
|
@ -286,7 +286,8 @@ implementation
|
|||||||
resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
|
resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if right.nodetype=ordconstn then
|
if (right.nodetype=ordconstn) and
|
||||||
|
(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
|
||||||
begin
|
begin
|
||||||
if nodetype=divn then
|
if nodetype=divn then
|
||||||
genOrdConstNodeDiv
|
genOrdConstNodeDiv
|
||||||
|
@ -181,8 +181,10 @@ asm
|
|||||||
|
|
||||||
tst r1, #4
|
tst r1, #4
|
||||||
strne r2,[r3],#4
|
strne r2,[r3],#4
|
||||||
|
{$ifdef CPUARM_HAS_ALL_MEM}
|
||||||
tst r1, #2
|
tst r1, #2
|
||||||
strneh r2,[r3],#2
|
strneh r2,[r3],#2
|
||||||
|
{$endif CPUARM_HAS_ALL_MEM}
|
||||||
tst r1, #1
|
tst r1, #1
|
||||||
strneb r2,[r3],#1
|
strneb r2,[r3],#1
|
||||||
{$ifdef CPUARM_HAS_BX}
|
{$ifdef CPUARM_HAS_BX}
|
||||||
|
Loading…
Reference in New Issue
Block a user