mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 19:29:26 +02:00
Fixed Bsf* functions on platforms that support RBIT
Fixed stackframe epilogue code for Thumb2 to allow proper processing of interrupts git-svn-id: branches/laksen/arm-embedded@22813 -
This commit is contained in:
parent
4e84431dde
commit
628d46f2d3
@ -160,8 +160,6 @@ unit cgcpu;
|
||||
procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
|
||||
procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override;
|
||||
|
||||
procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); override;
|
||||
|
||||
function handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference; override;
|
||||
|
||||
procedure a_loadmm_reg_reg(list: TAsmList; fromsize, tosize : tcgsize;reg1, reg2: tregister;shuffle : pmmshuffle); override;
|
||||
@ -1487,6 +1485,12 @@ unit cgcpu;
|
||||
list.Concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,31));
|
||||
list.Concat(taicpu.op_reg_reg_const(A_AND,dst,dst,255));
|
||||
end
|
||||
else if CPUARM_HAS_RBIT in cpu_capabilities[current_settings.cputype] then
|
||||
begin
|
||||
list.Concat(taicpu.op_reg_reg(A_RBIT,dst,src));
|
||||
list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst));
|
||||
list.Concat(taicpu.op_reg_reg(A_UXTB,dst,dst));
|
||||
end
|
||||
else
|
||||
internalerror(201209041);
|
||||
end;
|
||||
@ -3782,71 +3786,42 @@ unit cgcpu;
|
||||
inc(stackmisalignment,4);
|
||||
|
||||
stackmisalignment:=stackmisalignment mod current_settings.alignment.localalignmax;
|
||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
LocalSize:=current_procinfo.calc_stackframe_size;
|
||||
if (LocalSize<>0) or
|
||||
((stackmisalignment<>0) and
|
||||
((pi_do_call in current_procinfo.flags) or
|
||||
(po_assembler in current_procinfo.procdef.procoptions))) then
|
||||
begin
|
||||
localsize:=align(localsize+stackmisalignment,current_settings.alignment.localalignmax)-stackmisalignment;
|
||||
if not(is_shifter_const(LocalSize,shift)) then
|
||||
begin
|
||||
a_reg_alloc(list,NR_R12);
|
||||
a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
|
||||
a_reg_dealloc(list,NR_R12);
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
|
||||
end;
|
||||
end;
|
||||
|
||||
if regs=[] then
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
|
||||
LocalSize:=current_procinfo.calc_stackframe_size;
|
||||
if (LocalSize<>0) or
|
||||
((stackmisalignment<>0) and
|
||||
((pi_do_call in current_procinfo.flags) or
|
||||
(po_assembler in current_procinfo.procdef.procoptions))) then
|
||||
begin
|
||||
localsize:=align(localsize+stackmisalignment,current_settings.alignment.localalignmax)-stackmisalignment;
|
||||
if not(is_shifter_const(LocalSize,shift)) then
|
||||
begin
|
||||
a_reg_alloc(list,NR_R12);
|
||||
a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
|
||||
list.concat(taicpu.op_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_R12));
|
||||
a_reg_dealloc(list,NR_R12);
|
||||
end
|
||||
else
|
||||
begin
|
||||
reference_reset(ref,4);
|
||||
ref.index:=NR_STACK_POINTER_REG;
|
||||
ref.addressmode:=AM_PREINDEXED;
|
||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_FD));
|
||||
a_reg_dealloc(list,NR_R12);
|
||||
list.concat(taicpu.op_reg_const(A_ADD,NR_STACK_POINTER_REG,LocalSize));
|
||||
end;
|
||||
end
|
||||
end;
|
||||
|
||||
if regs=[] then
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
|
||||
else
|
||||
begin
|
||||
{ restore int registers and return }
|
||||
list.concat(taicpu.op_reg_reg(A_MOV, NR_STACK_POINTER_REG, NR_FRAME_POINTER_REG));
|
||||
{ Add 4 to SP to make it point to an "imaginary PC" which the paramanager assumes is there(for normal ARM) }
|
||||
list.concat(taicpu.op_reg_const(A_ADD, NR_STACK_POINTER_REG, 4));
|
||||
|
||||
reference_reset(ref,4);
|
||||
ref.index:=NR_STACK_POINTER_REG;
|
||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_DB));
|
||||
ref.addressmode:=AM_PREINDEXED;
|
||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_FD));
|
||||
end;
|
||||
end
|
||||
else
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14));
|
||||
end;
|
||||
|
||||
procedure Tthumb2cgarm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister);
|
||||
begin
|
||||
if reverse then
|
||||
begin
|
||||
list.Concat(taicpu.op_reg_reg(A_CLZ,dst,src));
|
||||
list.Concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,31));
|
||||
list.Concat(taicpu.op_reg_reg(A_UXTB,dst,dst));
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.Concat(taicpu.op_reg_reg(A_RBIT,dst,src));
|
||||
list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst));
|
||||
list.Concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,31));
|
||||
list.Concat(taicpu.op_reg_reg(A_UXTB,dst,dst));
|
||||
end
|
||||
end;
|
||||
|
||||
function Tthumb2cgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
||||
var
|
||||
tmpreg : tregister;
|
||||
|
@ -1083,12 +1083,12 @@ Const
|
||||
{ cpu_armv5tej } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP],
|
||||
{ cpu_armv6 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ cpu_armv6k } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ cpu_armv6t2 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ 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],
|
||||
{ cpu_armv6z } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ 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_LDREX],
|
||||
{ cpu_armv7a } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ cpu_armv7r } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
|
||||
{ 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],
|
||||
{ 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],
|
||||
{ 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],
|
||||
{ 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_IDIV],
|
||||
{ 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_IDIV]
|
||||
);
|
||||
|
@ -818,7 +818,7 @@ function SarInt64(Const AValue : Int64;const Shift : Byte = 1): Int64; [external
|
||||
{$endif FPC_HAS_INTERNAL_SAR_QWORD}
|
||||
|
||||
{$ifdef FPC_HAS_INTERNAL_BSF}
|
||||
{$if defined(cpui386) or defined(cpux86_64)}
|
||||
{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)}
|
||||
{$define FPC_HAS_INTERNAL_BSF_BYTE}
|
||||
{$define FPC_HAS_INTERNAL_BSF_WORD}
|
||||
{$define FPC_HAS_INTERNAL_BSF_DWORD}
|
||||
|
Loading…
Reference in New Issue
Block a user