aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorDavid Jones2005-03-02 10:19:00 +0000
committerDavid Jones2005-03-02 10:19:00 +0000
commit7c5adee6b2a43224406395a4bb591a3c43fbdccb (patch)
tree08433d5c5c1da126bf08d68c4456af0bcccac020 /mps/code
parentdc49e179da91b5573a5388be6559070278aa50e8 (diff)
parentd751349d259b5f8ec8a67de1cf1851d7a5e97d0b (diff)
downloademacs-7c5adee6b2a43224406395a4bb591a3c43fbdccb.tar.gz
emacs-7c5adee6b2a43224406395a4bb591a3c43fbdccb.zip
Mps: stack scanner for os x / powerpc
Copied from Perforce Change: 147226 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/ssxcpp.s149
-rw-r--r--mps/code/xcppgc.gmk5
2 files changed, 152 insertions, 2 deletions
diff --git a/mps/code/ssxcpp.s b/mps/code/ssxcpp.s
new file mode 100644
index 00000000000..07159c42cac
--- /dev/null
+++ b/mps/code/ssxcpp.s
@@ -0,0 +1,149 @@
1# ssxcpp.s: STACK SCANNING FOR MAC OS X / POWERPC
2#
3# .quote.why: The following is in quotes because otherwise the
4# preprocessor seems to barf.
5# "$Header$"
6#
7# Copyright (c) 2005 Ravenbrook Limited. See end of file for license.
8#
9# .readership: Any MPS developer that is prepared to read PowerPC
10# assembly code in GNU 'as' syntax.
11#
12#
13# It's possible that since this is mostly PowerPC and GNU 'as' that we
14# could use the same code for lippgc. See .future.abi
15#
16#
17# REFERENCES
18#
19# [OSXAG] "Introduction to Mac OS X Assembler Guide",
20# http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
21# http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/Assembler.pdf
22#
23# [PEM] "PowerPC Microprocessor Family: The Programming Environments for
24# 32-bit Microprocessors", Motorola, 1997-01. MPCFPE32B/AD REV.1
25#
26# [MORT] "Introduction to Mach-O Runtime Architecture",
27# http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html
28# http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/MachORuntime.pdf
29#
30# [MORT] Chapter 2 is the place to go for the stack layout. But it is
31# still a bit vague. For example, what is the exact format of the
32# Linkage Area?
33#
34#
35# Stack Layout and Register Usage
36#
37# Let SPEP be the value of the stack pointer (r1) on entry to the
38# function. r1 is the Stack Pointer, descending full stack (that is
39# -4(r1) is the address of the next available free slot on the stack).
40#
41# On entry, stack looks like (numerically higher addresses appear higher
42# up the page, stack grows down (towards address 0) in memory and on
43# paper):
44#
45# | |
46# +-----------------------------------+
47# | -- Parameter area -- |
48# | Lowest addresses have leftmost |
49# | actual arguments. |
50# | Note that some actual arguments |
51# | may be in registers. They |
52# | still have a slot reserved in |
53# | this area, even if the value is |
54# | not written in. |
55# +-----------------------------------+
56# | -- Linkage area -- |
57# | Apparently this is 24 bytes long. |
58# | (See [MORT] Listing 2-1) |
59# | 12(SPEP)-23(SPEP) unknown |
60# | 8(SPEP) - optional lr |
61# | 4(SPEP) - optional cr |
62# | 0(SPEP) - previous SPEP |
63# +-----------------------------------+
64# 8(SPEP) - available to store the callee's lr if desired.
65# 4(SPEP) - available to store the callee's cr if desired.
66# 0(SPEP) - not available. The caller saves their SPEP here. In other
67# words, this points to the highest address of the caller's frame. The
68# callee will decrement sp and store SPEP at the new sp, thus creating a
69# new linkage area in preparation for calling another function.
70#
71# Note that the callee can access locations -1(SPEP) to -224(SPEP)
72# without changing the stack pointer. This is called a Red Zone (see
73# [MORT] Chapter 2, section "The Red Zone"). This means that we must
74# overscan when scanning the stacks of other threads.
75#
76# [MORT] Table 2-4 specifies which registers are saved (required to be
77# preserved by a callee when called, aka nonvolatile). They are: r1,
78# r13-r31, fr14-fr31, v20-v31, VRSAVE, cr2-cr4.
79#
80# Stack Scanner Design
81#
82# All we have to do is create a stack frame, push the saved registers
83# onto it, and call TraceScanArea with appropriate arguments.
84# We assume that of the saved registers, only the general purpose ones
85# can contain roots (in other words the client doesn't store pointers in
86# floating pointer registers, and other silliness). So we'll only store
87# r13 through to r31. r1 will be stored in the callee's new linkage
88# area, as per convention. lr will be stored in the caller's linkage
89# area, as per convention. CTR (a future PC value, so a potential root)
90# is volatile so cannot be a root.
91#
92# Future Directions
93#
94# .future.clear: We could poke all the stack locations that we have
95# access to and set them to 0 (the ones that we are not using), just
96# in case any false references are hiding there.
97#
98# .future.abi:
99# One can imagine a sort of minimal ABI version that pushed
100# all registers and only used stack space that it had reserved itself.
101# We would, alas, still have to assume that r1 was SP though.
102#
103# To do this we would need to:
104# - save more registers
105# - possibly not use the caller's stack
106
107# Exported symbols
108.globl _StackScan
109
110# Imported symbols
111.globl _TraceScanArea
112
113linkageArea = 24 ; size of linkage area to create
114paramArea = 12 ; size of param area to create
115# .local.size: this size is directly related to what registers we save.
116localArea = 76 ; size of local workspace (for 19 registers, r13-r31)
117# A throwaway comment in [MORT] p32 "The called routine is responsible
118# for allocating its own stack frame, making sure to preserve 16-byte
119# alignment on the stack" implies that the stack must always be 16-byte
120# aligned. Thus, this sum, frameSize, must be a multiple of 16. 24 +
121# 12 + 76 = 112 = 7*16, so much for the abstraction.
122frameSize = linkageArea + paramArea + localArea
123
124_StackScan:
125# r1 is SPEP
126 mflr r0
127# value of localArea depends on r13, see .local.size
128 stmw r13, -localArea(r1)
129 stw r0, 8(r1)
130 stwu r1, -frameSize(r1)
131# r1 + frameSize is SPEP
132
133# setup arguments for call to TraceScanArea, and call it
134# First Argument, ScanState, is our first argument, already in r3.
135# Arguments are processed out of order because of the dependency on r4
136# Third Argument: highest stack address.
137 mr r5, r4
138# Second Argument: lowest stack address.
139 mr r4, r1
140 bl _TraceScanArea
141
142 lwz r1, 0(r1)
143# r1 is SPEP again
144 lwz r0, 8(r1)
145 mtlr r0
146# See .local.size
147 lmw r13, -localArea(r1)
148 li r3, 0
149 blr
diff --git a/mps/code/xcppgc.gmk b/mps/code/xcppgc.gmk
index f26f10fc064..6ae29f5d5b9 100644
--- a/mps/code/xcppgc.gmk
+++ b/mps/code/xcppgc.gmk
@@ -1,12 +1,13 @@
1# xcppgc.gmk: BUILD FOR MACOS X (CARBON)/POWERPC/GCC PLATFORM 1# xcppgc.gmk: BUILD FOR MACOS X (CARBON)/POWERPC/GCC PLATFORM
2# 2#
3# $Id$ 3# $Id$
4# Copyright (c) 2001 Ravenbrook Limited. See end of file for license. 4# Copyright (c) 2001,2005 Ravenbrook Limited. See end of file for license.
5 5
6PFM = xcppgc 6PFM = xcppgc
7 7
8MPMPF = lockan.c than.c vmxc.c \ 8MPMPF = lockan.c than.c vmxc.c \
9 protan.c prmcan.c span.c ssan.c 9 protan.c prmcan.c span.c
10MPMS = ssxcpp.s
10SWPF = than.c vmxc.c protsw.c prmcan.c ssan.c 11SWPF = than.c vmxc.c protsw.c prmcan.c ssan.c
11 12
12LIBS = 13LIBS =