mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 01:09:31 +02:00
* use BLX instead of "mov r14, r15; mov r15, reg" for a_call_reg on ARMv6
and above, so this also works when calling thumb code (should actually also be done for ARMv5T, but we don't have a monicker for that yet) * use BX instead of "mov r15, r14" for simple returns from subroutines on ARMv6+ to support returning to thumb code from ARM code (idem) git-svn-id: trunk@14332 -
This commit is contained in:
parent
fa42b022d2
commit
fbebd87593
@ -527,8 +527,14 @@ unit cgcpu;
|
||||
|
||||
procedure tcgarm.a_call_reg(list : TAsmList;reg: tregister);
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,reg));
|
||||
{ check not really correct: should only be used for non-Thumb cpus }
|
||||
if (current_settings.cputype<cpu_armv6) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,reg));
|
||||
end
|
||||
else
|
||||
list.concat(taicpu.op_reg(A_BLX, reg));
|
||||
{
|
||||
the compiler does not properly set this flag anymore in pass 1, and
|
||||
for now we only need it after pass 2 (I hope) (JM)
|
||||
@ -543,8 +549,7 @@ unit cgcpu;
|
||||
begin
|
||||
a_reg_alloc(list,NR_R12);
|
||||
a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_R12);
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R12));
|
||||
a_call_reg(list,NR_R12);
|
||||
a_reg_dealloc(list,NR_R12);
|
||||
include(current_procinfo.flags,pi_do_call);
|
||||
end;
|
||||
@ -1653,7 +1658,12 @@ unit cgcpu;
|
||||
end;
|
||||
|
||||
if regs=[] then
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
|
||||
begin
|
||||
if (current_settings.cputype<cpu_armv6) then
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14))
|
||||
else
|
||||
list.concat(taicpu.op_reg(A_BX,NR_R14))
|
||||
end
|
||||
else
|
||||
begin
|
||||
reference_reset(ref,4);
|
||||
@ -1670,8 +1680,10 @@ unit cgcpu;
|
||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_EA));
|
||||
end;
|
||||
end
|
||||
else if (current_settings.cputype<cpu_armv6) then
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14))
|
||||
else
|
||||
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14));
|
||||
list.concat(taicpu.op_reg(A_BX,NR_R14))
|
||||
end;
|
||||
|
||||
|
||||
|
@ -137,7 +137,11 @@ Procedure FillChar(var x;count:longint;value:byte);assembler;nostackframe;
|
||||
asm
|
||||
// less than 0?
|
||||
cmp r1,#0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
movlt pc,lr
|
||||
{$else}
|
||||
bxlt lr
|
||||
{$endif}
|
||||
mov r3,r0
|
||||
cmp r1,#8 // at least 8 bytes to do?
|
||||
blt .LFillchar2
|
||||
@ -168,7 +172,11 @@ asm
|
||||
bge .LFillchar1
|
||||
.LFillchar2:
|
||||
movs r1,r1 // anything left?
|
||||
moveq pc,lr
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
moveq pc,lr
|
||||
{$else}
|
||||
bxeq lr
|
||||
{$endif}
|
||||
rsb r1,r1,#7
|
||||
add pc,pc,r1,lsl #2
|
||||
mov r0,r0
|
||||
@ -179,7 +187,11 @@ asm
|
||||
strb r2,[r3],#1
|
||||
strb r2,[r3],#1
|
||||
strb r2,[r3],#1
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_FILLCHAR}
|
||||
|
||||
@ -191,7 +203,11 @@ asm
|
||||
pld [r1]
|
||||
// count <=0 ?
|
||||
cmp r2,#0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
movle pc,lr
|
||||
{$else}
|
||||
bxle lr
|
||||
{$endif}
|
||||
// overlap?
|
||||
cmp r1,r0
|
||||
bls .Lnooverlap
|
||||
@ -204,7 +220,11 @@ asm
|
||||
ldrb r3,[r0,r2]
|
||||
strb r3,[r1,r2]
|
||||
bne .Loverlapped
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
.Lnooverlap:
|
||||
// less then 16 bytes to copy?
|
||||
cmp r2,#8
|
||||
@ -247,20 +267,32 @@ asm
|
||||
str r3,[r1],#4
|
||||
bcs .Ldwordloop
|
||||
cmp r2,#0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
moveq pc,lr
|
||||
{$else}
|
||||
bxeq lr
|
||||
{$endif}
|
||||
.Lbyteloop:
|
||||
subs r2,r2,#1
|
||||
ldrb r3,[r0],#1
|
||||
strb r3,[r1],#1
|
||||
bne .Lbyteloop
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure Move_blended(const source;var dest;count:longint);assembler;nostackframe;
|
||||
asm
|
||||
// count <=0 ?
|
||||
cmp r2,#0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
movle pc,lr
|
||||
{$else}
|
||||
bxle lr
|
||||
{$endif}
|
||||
// overlap?
|
||||
cmp r1,r0
|
||||
bls .Lnooverlap
|
||||
@ -273,7 +305,11 @@ asm
|
||||
ldrb r3,[r0,r2]
|
||||
strb r3,[r1,r2]
|
||||
bne .Loverlapped
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
.Lnooverlap:
|
||||
// less then 16 bytes to copy?
|
||||
cmp r2,#8
|
||||
@ -311,13 +347,21 @@ asm
|
||||
str r3,[r1],#4
|
||||
bcs .Ldwordloop
|
||||
cmp r2,#0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
moveq pc,lr
|
||||
{$else}
|
||||
bxeq lr
|
||||
{$endif}
|
||||
.Lbyteloop:
|
||||
subs r2,r2,#1
|
||||
ldrb r3,[r0],#1
|
||||
strb r3,[r1],#1
|
||||
bne .Lbyteloop
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
@ -492,7 +536,11 @@ asm
|
||||
terminating 0, due to the known carry flag sbc can do this.*)
|
||||
sbc r0,r1,r0
|
||||
.Ldone:
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc,lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
.L01010101:
|
||||
.long 0x01010101
|
||||
end;
|
||||
@ -512,7 +560,7 @@ asm
|
||||
cmp r2, #0
|
||||
bne .Lloop
|
||||
mov r0, r1
|
||||
mov pc, lr
|
||||
bx lr
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
@ -528,7 +576,7 @@ asm
|
||||
mov r0, r1
|
||||
// unlock and return
|
||||
str r2, [r3]
|
||||
mov pc, lr
|
||||
bx lr
|
||||
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
@ -546,7 +594,7 @@ asm
|
||||
cmp r2, #0
|
||||
bne .Lloop
|
||||
mov r0, r1
|
||||
mov pc, lr
|
||||
bx lr
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
@ -562,7 +610,7 @@ asm
|
||||
mov r0, r1
|
||||
// unlock and return
|
||||
str r2, [r3]
|
||||
mov pc, lr
|
||||
bx lr
|
||||
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
@ -580,7 +628,7 @@ asm
|
||||
cmp r3, #0
|
||||
bne .Lloop
|
||||
mov r0, r2
|
||||
mov pc, lr
|
||||
bx lr
|
||||
{$else}
|
||||
swp r1, r1, [r0]
|
||||
mov r0,r1
|
||||
@ -597,7 +645,7 @@ asm
|
||||
cmp r3, #0
|
||||
bne .Lloop
|
||||
mov r0, r2
|
||||
mov pc, lr
|
||||
bx lr
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
@ -614,7 +662,7 @@ asm
|
||||
// unlock and return
|
||||
mov r2, #0
|
||||
str r2, [r3]
|
||||
mov pc, lr
|
||||
bx lr
|
||||
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
@ -633,7 +681,7 @@ asm
|
||||
cmp r12, #0
|
||||
bne .Lloop
|
||||
mov r0, r3
|
||||
mov pc, lr
|
||||
bx lr
|
||||
{$else}
|
||||
// lock
|
||||
ldr r12, .Lfpc_system_lock
|
||||
@ -650,7 +698,7 @@ asm
|
||||
// unlock and return
|
||||
mov r3, #0
|
||||
str r3, [r12]
|
||||
mov pc, lr
|
||||
bx lr
|
||||
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
|
@ -107,12 +107,20 @@ asm
|
||||
.Ldiv_next:
|
||||
bcs .Ldiv_loop
|
||||
mov r0, r3
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc, lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
.Ldiv_by_0:
|
||||
mov r0, #200
|
||||
mov r1, r11
|
||||
bl handleerrorframe
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc, lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$else}
|
||||
mov r3, #0
|
||||
@ -167,12 +175,20 @@ asm
|
||||
.Ldiv_next:
|
||||
bcs .Ldiv_loop
|
||||
mov r0, r3
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc, lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
.Ldiv_by_0:
|
||||
mov r0, #200
|
||||
mov r1, r11
|
||||
bl handleerrorframe
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
|
||||
mov pc, lr
|
||||
{$else}
|
||||
bx lr
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
@ -307,6 +307,7 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
|
||||
begin
|
||||
cw:=VFP_GetCW and not(_VFP_ENABLE_ALL);
|
||||
|
||||
{$ifndef darwin}
|
||||
if exInvalidOp in Mask then
|
||||
cw:=cw or _VFP_ENABLE_IM;
|
||||
|
||||
@ -324,6 +325,7 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
|
||||
|
||||
if exPrecision in Mask then
|
||||
cw:=cw or _VFP_ENABLE_PM;
|
||||
{$endif}
|
||||
VFP_SetCW(cw);
|
||||
result:=Mask;
|
||||
|
||||
|
@ -34,7 +34,7 @@ function setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_SETJM
|
||||
{$else}
|
||||
stmia r0,{v1-v6, sl, fp, sp, lr}
|
||||
mov r0,#0
|
||||
mov pc,lr
|
||||
bx lr
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user