diff options
author | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-12-27 18:47:22 -0500 |
---|---|---|
committer | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-12-27 18:47:22 -0500 |
commit | b7c2c37a48f8f433c72e1404c71069eb184cdff0 (patch) | |
tree | 23c4c7f8adac437135566989004944997bf7698a | |
parent | 947ba577d998345323948d4e17478ce4861b5bac (diff) | |
parent | a78702fc9a4e5720c17ed1a37b45e29e59810d27 (diff) |
Merge branch 'libc' of https://github.com/ProjectRevoTPP/agbcc
-rw-r--r-- | libc/arm/setjmp.S | 102 | ||||
-rw-r--r-- | libc/arm/trap.S | 93 |
2 files changed, 195 insertions, 0 deletions
diff --git a/libc/arm/setjmp.S b/libc/arm/setjmp.S new file mode 100644 index 0000000..eab8e21 --- /dev/null +++ b/libc/arm/setjmp.S @@ -0,0 +1,102 @@ +/* This is a simple version of setjmp and longjmp. + + Nick Clifton, Cygnus Solutions, 13 June 1997. */ + +/* ANSI concatenation macros. */ +#define CONCAT(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +#ifdef __USER_LABEL_PREFIX__ +#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name) +#else +#error __USER_LABEL_PREFIX__ is not defined +#endif + + + .text + .code 32 + .align 2 + +/* int setjmp (jmp_buf); */ + .globl FUNCTION(setjmp) +FUNCTION(setjmp): + + /* Save all the callee-preserved registers into the jump buffer. */ + stmea a1!, { v1-v7, fp, ip, sp, lr } + +#if 0 /* Simulator does not cope with FP instructions yet.... */ +#ifndef __SOFTFP__ + /* Save the floating point registers */ + sfmea f4, 4, [a1] +#endif +#endif + /* When setting up the jump buffer return 0. */ + mov a1, #0 + + /* Return to caller, see comment in longjmp below */ +#ifdef __APCS_26__ + movs pc, lr +#else + tst lr, #1 + moveq pc, lr +.word 0xe12fff1e /* bx lr */ +#endif + + +/* volatile void longjmp (jmp_buf, int); */ + .globl FUNCTION(longjmp) +FUNCTION(longjmp): + + /* If we have stack extension code it ought to be handled here. */ + + /* Restore the registers, retrieving the state when setjmp() was called. */ + ldmfd a1!, { v1-v7, fp, ip, sp, lr } + +#if 0 /* Simulator does not cope with FP instructions yet.... */ +#ifndef __SOFTFP__ + /* Restore floating point registers as well */ + lfmfd f4, 4, [a1] +#endif +#endif + /* Put the return value into the integer result register. + But if it is zero then return 1 instead. */ + movs a1, a2 + moveq a1, #1 + + /* Arm/Thumb interworking support: + + The interworking scheme expects functions to use a BX instruction + to return control to their parent. Since we need this code to work + in both interworked and non-interworked environments as well as with + older processors which do not have the BX instruction we do the + following: + Test the return address. + If the bottom bit is clear perform an "old style" function exit. + (We know that we are in ARM mode and returning to an ARM mode caller). + Otherwise use the BX instruction to perform the function exit. + + We know that we will never attempt to perform the BX instruction on + an older processor, because that kind of processor will never be + interworked, and a return address with the bottom bit set will never + be generated. + + In addition, we do not actually assemble the BX instruction as this would + require us to tell the assembler that the processor is an ARM7TDMI and + it would store this information in the binary. We want this binary to be + able to be linked with binaries compiled for older processors however, so + we do not want such information stored there. + + If we are running using the APCS-26 convention however, then we never + test the bottom bit, because this is part of the processor status. + Instead we just do a normal return, since we know that we cannot be + returning to a Thumb caller - the Thumb doe snot support APCS-26 + */ + +#ifdef __APCS_26__ + movs pc, lr +#else + tst lr, #1 + moveq pc, lr +.word 0xe12fff1e /* bx lr */ +#endif + diff --git a/libc/arm/trap.S b/libc/arm/trap.S new file mode 100644 index 0000000..328fabc --- /dev/null +++ b/libc/arm/trap.S @@ -0,0 +1,93 @@ + /* Run-time exception support */ +#include "swi.h" + +/* .text is used instead of .section .text so it works with arm-aout too. */ + .text + .align 0 + .global __rt_stkovf_split_big + .global __rt_stkovf_split_small + +/* The following functions are provided for software stack checking. + If hardware stack-checking is being used then the code can be + compiled without the PCS entry checks, and simply rely on VM + management to extend the stack for a thread. + + The stack extension event occurs when the PCS function entry code + would result in a stack-pointer beneath the stack-limit register + value. The system relies on the following map: + + +-----------------------------------+ <-- end of stack block + | ... | + | ... | + | active stack | + | ... | <-- sp (stack-pointer) somewhere in here + | ... | + +-----------------------------------+ <-- sl (stack-limit) + | stack-extension handler workspace | + +-----------------------------------+ <-- base of stack block + + The "stack-extension handler workspace" is an amount of memory in + which the stack overflow support code must execute. It must be + large enough to deal with the worst case path through the extension + code. At the moment the compiler expects this to be AT LEAST + 256bytes. It uses this fact to code functions with small local + data usage within the overflow space. + + In a true target environment We may need to increase the space + between sl and the true limit to allow for the stack extension + code, SWI handlers and for undefined instruction handlers of the + target environment. */ + +__rt_stkovf_split_small: + mov ip,sp @ Ensure we can calculate the stack required + @ and fall through to... +__rt_stkovf_split_big: + @ in: sp = current stack-pointer (beneath stack-limit) + @ sl = current stack-limit + @ ip = low stack point we require for the current function + @ lr = return address into the current function + @ fp = frame-pointer + @ original sp --> +----------------------------------+ + @ | pc (12 ahead of PCS entry store) | + @ current fp ---> +----------------------------------+ + @ | lr (on entry) pc (on exit) | + @ +----------------------------------+ + @ | sp ("original sp" on entry) | + @ +----------------------------------+ + @ | fp (on entry to function) | + @ +----------------------------------+ + @ | | + @ | ..argument and work registers.. | + @ | | + @ current sp ---> +----------------------------------+ + @ + @ The "current sl" is somewhere between "original sp" and "current sp" + @ but above "true sl". The "current sl" should be at least 256bytes + @ above the "true sl". The 256byte stack guard should be large enough + @ to deal with the worst case function entry stacking (160bytes) plus + @ the stack overflow handler stacking requirements, plus the stack + @ required for the memory allocation routines. + @ + @ Normal PCS entry (before stack overflow check) can stack 16 + @ standard registers (64bytes) and 8 floating point registers + @ (96bytes). This gives a minimum stack guard of 160bytes (excluding + @ the stack required for the code). (Actually only a maximum of + @ 14standard registers are ever stacked on entry to a function). + @ + @ NOTE: Structure returns are performed by the caller allocating a + @ dummy space on the stack and passing in a "phantom" arg1 into + @ the function. This means that we do not need to worry about + @ preserving the stack under "sp" even on function return. + @ + @ Code should never poke values beneath sp. The sp register + @ should always be "dropped" first to cover the data. This + @ protects the data against any events that may try and use + @ the stack. + + SUB ip, sp, ip @ extra stack required for function + @ Add stack extension code here. If desired a new stack chunk + @ can be allocated, and the register state updated suitably. + + @ We now know how much extra stack the function requires. + @ Terminate the program for the moment: + swi SWI_Exit |