1#if defined(__ppc64__)
2#define MODE_CHOICE(x, y) y
3#else
4#define MODE_CHOICE(x, y) x
5#endif
6
7#define machine_choice	MODE_CHOICE(ppc7400,ppc64)
8
9; Define some pseudo-opcodes for size-independent load & store of GPRs ...
10#define lgu		MODE_CHOICE(lwzu, ldu)
11#define lg		MODE_CHOICE(lwz,ld)
12#define sg		MODE_CHOICE(stw,std)
13#define sgu		MODE_CHOICE(stwu,stdu)
14
15; ... and the size of GPRs and their storage indicator.
16#define GPR_BYTES	MODE_CHOICE(4,8)
17#define LOG2_GPR_BYTES	MODE_CHOICE(2,3)	/* log2(GPR_BYTES) */
18#define g_long		MODE_CHOICE(long, quad)	/* usage is ".g_long" */
19
20; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
21#define LINKAGE_SIZE	MODE_CHOICE(24,48)
22#define PARAM_AREA	MODE_CHOICE(32,64)
23#define SAVED_LR_OFFSET	MODE_CHOICE(8,16)	/* save position for lr */
24
25; The whole stack frame **MUST** be 16byte-aligned.
26#define SAVE_SIZE (LINKAGE_SIZE+PARAM_AREA)
27
28#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
29; We no longer need the pic symbol stub for Darwin >= 9.
30#define BLGCP1	_GC_push_one
31#undef WANT_STUB
32#else
33#define BLGCP1	L_GC_push_one$stub
34#define WANT_STUB
35#endif
36
37	.machine machine_choice
38
39; GC_push_regs function. Under some optimization levels GCC will clobber
40; some of the non-volatile registers before we get a chance to save them
41; therefore, this cannot be inline asm.
42
43.text
44	.align LOG2_GPR_BYTES
45	.globl _GC_push_regs
46_GC_push_regs:
47
48    ; Prolog
49	mflr r0
50	sg r0,SAVED_LR_OFFSET(r1)
51	sgu r1,-SAVE_SIZE(r1)
52
53L_body:
54    ; 'Push' r13-r31
55	mr r3,r13
56	bl BLGCP1
57	mr r3,r14
58	bl BLGCP1
59	mr r3,r15
60	bl BLGCP1
61	mr r3,r16
62	bl BLGCP1
63	mr r3,r17
64	bl BLGCP1
65	mr r3,r18
66	bl BLGCP1
67	mr r3,r19
68	bl BLGCP1
69	mr r3,r20
70	bl BLGCP1
71	mr r3,r21
72	bl BLGCP1
73	mr r3,r22
74	bl BLGCP1
75	mr r3,r23
76	bl BLGCP1
77	mr r3,r24
78	bl BLGCP1
79	mr r3,r25
80	bl BLGCP1
81	mr r3,r26
82	bl BLGCP1
83	mr r3,r27
84	bl BLGCP1
85	mr r3,r28
86	bl BLGCP1
87	mr r3,r29
88	bl BLGCP1
89	mr r3,r30
90	bl BLGCP1
91	mr r3,r31
92	bl BLGCP1
93
94L_epilog:
95    ; Epilog
96	lg r0,SAVE_SIZE+SAVED_LR_OFFSET(r1)
97	addi r1,r1,SAVE_SIZE
98	mtlr r0
99
100    ; Return
101	blr
102LFE0:
103
104; eh frames, for those that want 'em.
105
106#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
107#define EH_FRAME_OFFSET MODE_CHOICE(0x40,0x70)
108
109	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
110EH_frame1:
111	.set L$set$0,LECIE1-LSCIE1
112	.long L$set$0	; Length of Common Information Entry
113LSCIE1:
114	.long	0	; CIE Identifier Tag
115	.byte	0x1	; CIE Version
116	.ascii "zR\0"	; CIE Augmentation
117	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
118	.byte	EH_DATA_ALIGN_FACT	; sleb128 -4/-8; CIE Data Alignment Factor
119	.byte	0x41	; CIE RA Column
120	.byte	0x1	; uleb128 0x1; Augmentation size
121	.byte	0x10	; FDE Encoding (pcrel)
122	.byte	0xc	; DW_CFA_def_cfa
123	.byte	0x1	; uleb128 0x1
124	.byte	0	; uleb128 0
125	.align	LOG2_GPR_BYTES
126LECIE1:
127
128	.globl _GC_push_regs.eh
129_GC_push_regs.eh:
130LSFDE1:
131	.set L$set$1,LEFDE1-LASFDE1
132	.long L$set$1	; FDE Length
133LASFDE1:
134	.long	LASFDE1-EH_frame1	; FDE CIE offset
135	.g_long	_GC_push_regs-.	; FDE initial location
136	.set L$set$2,LFE0-_GC_push_regs
137	.g_long L$set$2	; FDE address range
138	.byte	0	; uleb128 0; Augmentation size
139	.byte	0x4	; DW_CFA_advance_loc4
140	.set L$set$3,L_body-_GC_push_regs
141	.long L$set$3
142	.byte	0xe	; DW_CFA_def_cfa_offset
143	.byte	EH_FRAME_OFFSET	; uleb128 0x40/0x70
144	.byte	0x11	; DW_CFA_offset_extended_sf
145	.byte	0x41	; uleb128 0x41
146	.byte	0x7e	; sleb128 -2
147	.byte	0x4	; DW_CFA_advance_loc4
148	.set L$set$4,L_epilog-L_body
149	.long L$set$4
150	.byte	0xe	; DW_CFA_def_cfa_offset
151	.byte	0	; uleb128 0
152	.align	LOG2_GPR_BYTES
153LEFDE1:
154
155	.data
156#ifdef WANT_STUB
157; PIC stub stuff, generated by GCC
158
159	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
160	.align LOG2_GPR_BYTES
161L_GC_push_one$stub:
162	.indirect_symbol _GC_push_one
163	mflr r0
164	bcl 20,31,L0$_GC_push_one
165L0$_GC_push_one:
166	mflr r11
167	addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
168	mtlr r0
169	lgu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
170	mtctr r12
171	bctr
172
173	.data
174	.lazy_symbol_pointer
175L_GC_push_one$lazy_ptr:
176	.indirect_symbol _GC_push_one
177	.g_long dyld_stub_binding_helper
178#endif
179