mirror of
https://github.com/pret/agbcc.git
synced 2026-03-21 17:44:20 -05:00
please actually work this time im asking nicely
This commit is contained in:
parent
6b611a3046
commit
947ba577d9
|
|
@ -29,8 +29,8 @@ stdlib/cfreer.o stdlib/malignr.o stdlib/vallocr.o stdlib/pvallocr.o \
|
|||
stdlib/mallinfor.o stdlib/mallstatsr.o stdlib/msizer.o stdlib/malloptr.o \
|
||||
stdio/vfiprintf.o
|
||||
|
||||
S_SRCS := arm/setjmp.S arm/trap.S
|
||||
S_OBJS := $(S_SRCS:%.S=%.o)
|
||||
S_SRCS := arm/setjmp.s arm/trap.s
|
||||
S_OBJS := $(S_SRCS:%.s=%.o)
|
||||
|
||||
OBJS := $(C_OBJS) $(S_OBJS)
|
||||
|
||||
|
|
|
|||
102
libc/arm/setjmp.s
Executable file
102
libc/arm/setjmp.s
Executable file
|
|
@ -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
|
||||
|
||||
93
libc/arm/trap.s
Executable file
93
libc/arm/trap.s
Executable file
|
|
@ -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
|
||||
Loading…
Reference in New Issue
Block a user