summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-04-05 19:25:20 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-04-05 19:25:20 +0000
commitb86ca81787a9e3556580ce7fd0b0aa9475f78173 (patch)
tree10a35b510ef6f00e5cd5ad6d926336a6c1527971
parent4bae118edd4d73681ed3cc3e0e90b5c13a2b3782 (diff)
downloadfpc-b86ca81787a9e3556580ce7fd0b0aa9475f78173.tar.gz
* patch by Jeppe Johansen to fix thumb2 epilog generation, resolves #18392
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@17252 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/arm/cgcpu.pas2
-rw-r--r--rtl/arm/thumb2.inc10
2 files changed, 10 insertions, 2 deletions
diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas
index c4feae5fc2..dfb75b83b8 100644
--- a/compiler/arm/cgcpu.pas
+++ b/compiler/arm/cgcpu.pas
@@ -3479,6 +3479,8 @@ unit cgcpu;
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;
diff --git a/rtl/arm/thumb2.inc b/rtl/arm/thumb2.inc
index c4948d9ca0..6271c6920d 100644
--- a/rtl/arm/thumb2.inc
+++ b/rtl/arm/thumb2.inc
@@ -77,12 +77,18 @@ asm
end;
{$ENDIF not INTERNAL_BACKTRACE}
+{
+ Stack frame on Thumb2:
+ LR <- FP
+ Old FP
+}
+
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
function get_caller_addr(framebp:pointer):pointer;assembler;
asm
movs r0,r0
beq .Lg_a_null
- ldr r0,[r0,#-4]
+ ldr r0,[r0]
.Lg_a_null:
end;
@@ -92,7 +98,7 @@ function get_caller_frame(framebp:pointer):pointer;assembler;
asm
movs r0,r0
beq .Lgnf_null
- ldr r0,[r0,#-12]
+ ldr r0,[r0,#-4]
.Lgnf_null:
end;