1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _MACH_I386_SDT_ISA_H
28#define	_MACH_I386_SDT_ISA_H
29
30/*
31 * Only define when testing.  This makes the calls into actual calls to
32 * test functions.
33 */
34/* #define DTRACE_CALL_TEST */
35
36#define DTRACE_STRINGIFY(s) #s
37#define DTRACE_TOSTRING(s) DTRACE_STRINGIFY(s)
38#if defined(KERNEL)
39/*
40 * For the kernel, set an explicit global label so the symbol can be located
41 */
42#ifdef __x86_64__
43#define DTRACE_LAB(p, n)		\
44   "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n)
45
46#define DTRACE_LABEL(p, n)		\
47      ".section __DATA, __data\n\t"	\
48      ".globl " DTRACE_LAB(p, n) "\n\t"	\
49       DTRACE_LAB(p, n) ":" ".quad 1f""\n\t"	\
50       ".text" "\n\t"			\
51	"1:"
52#else
53#define DTRACE_LAB(p, n)		\
54   "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n)
55
56#define DTRACE_LABEL(p, n)		\
57      ".section __DATA, __data\n\t"	\
58      ".globl " DTRACE_LAB(p, n) "\n\t"	\
59       DTRACE_LAB(p, n) ":" ".long 1f""\n\t"	\
60       ".text" "\n\t"			\
61	"1:"
62#endif
63#else	/* !KERNEL */
64#define DTRACE_LABEL(p, n)									\
65	"__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":"	"\n\t"
66#endif	/* !KERNEL */
67
68#ifdef DTRACE_CALL_TEST
69
70#define DTRACE_CALL(p,n)	\
71	DTRACE_LABEL(p,n)	\
72	DTRACE_CALL_INSN(p,n)
73
74#else
75
76#define DTRACE_CALL(p,n)	\
77	DTRACE_LABEL(p,n)	\
78	DTRACE_NOPS
79
80#endif
81
82#ifdef __x86_64__
83
84#define DTRACE_NOPS			\
85	"nop"			"\n\t"	\
86	"nop"			"\n\t"	\
87	"nop"			"\n\t"
88
89#define DTRACE_CALL_INSN(p,n)						\
90	"call _dtracetest" DTRACE_STRINGIFY(_##p##_##n)	"\n\t"
91
92#define ARG1_EXTENT	1
93#define ARGS2_EXTENT	2
94#define ARGS3_EXTENT	3
95#define ARGS4_EXTENT	4
96#define ARGS5_EXTENT	5
97#define ARGS6_EXTENT	6
98#define ARGS7_EXTENT	7
99#define ARGS8_EXTENT	8
100#define ARGS9_EXTENT	9
101#define ARGS10_EXTENT	10
102
103#define DTRACE_CALL0ARGS(provider, name)							\
104	asm volatile (										\
105		      DTRACE_CALL(provider, name)						\
106	              :										\
107	              :										\
108	);
109
110#define DTRACE_CALL1ARG(provider, name)								\
111	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
112		      DTRACE_CALL(provider, name)						\
113	              :										\
114	              : "r" (__dtrace_args)							\
115	              : "memory", "rdi"								\
116	);
117
118#define DTRACE_CALL2ARGS(provider, name)							\
119	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
120	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
121		      DTRACE_CALL(provider, name)						\
122	              :										\
123	              : "r" (__dtrace_args)							\
124	              : "memory", "rdi", "rsi"							\
125	);
126
127#define DTRACE_CALL3ARGS(provider, name)							\
128	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
129	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
130	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
131		      DTRACE_CALL(provider, name)						\
132	              :										\
133	              : "r" (__dtrace_args)							\
134	              : "memory", "rdi", "rsi", "rdx"						\
135	);
136
137#define DTRACE_CALL4ARGS(provider, name)							\
138	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
139	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
140	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
141	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
142		      DTRACE_CALL(provider, name)						\
143	              :										\
144	              : "r" (__dtrace_args)							\
145	              : "memory", "rdi", "rsi", "rdx", "rcx"					\
146	);
147
148#define DTRACE_CALL5ARGS(provider, name)							\
149	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
150	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
151	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
152	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
153	              "movq\t0x20(%0),%%r8"						"\n\t"	\
154		      DTRACE_CALL(provider, name)						\
155	              :										\
156	              : "r" (__dtrace_args)							\
157	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8"				\
158	);
159
160#define DTRACE_CALL6ARGS(provider, name)							\
161	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
162	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
163	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
164	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
165	              "movq\t0x20(%0),%%r8"						"\n\t"	\
166	              "movq\t0x28(%0),%%r9"						"\n\t"	\
167		      DTRACE_CALL(provider, name)						\
168	              :										\
169	              : "r" (__dtrace_args)							\
170	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9"			\
171	);
172
173#define DTRACE_CALL7ARGS(provider, name)							\
174	asm volatile ("subq\t$0x8,%%rsp"						"\n\t"	\
175	              "movq\t0x0(%0),%%rdi"						"\n\t"	\
176	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
177	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
178	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
179	              "movq\t0x20(%0),%%r8"						"\n\t"	\
180	              "movq\t0x28(%0),%%r9"						"\n\t"	\
181	              "movq\t0x30(%0),%%rax"						"\n\t"	\
182	              "movq\t%%rax,0x0(%%rsp)"						"\n\t"	\
183		      DTRACE_CALL(provider, name)						\
184	              "addq\t$0x8,%%rsp"						"\n\t"	\
185	              :										\
186	              : "r" (__dtrace_args)							\
187	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "rax"			\
188	);
189
190#endif // __x86_64__
191
192#ifdef __i386__
193
194#define DTRACE_NOPS			\
195	"nop"			"\n\t"	\
196	"leal 0(%%esi), %%esi"	"\n\t"
197
198#define DTRACE_CALL_INSN(p,n)						\
199	"call _dtracetest" DTRACE_STRINGIFY(_##p##_##n)	"\n\t"
200
201#define ARG1_EXTENT	1
202#define ARGS2_EXTENT	2
203#define ARGS3_EXTENT	4
204#define ARGS4_EXTENT	4
205#define ARGS5_EXTENT	8
206#define ARGS6_EXTENT	8
207#define ARGS7_EXTENT	8
208#define ARGS8_EXTENT	8
209#define ARGS9_EXTENT	12
210#define ARGS10_EXTENT	12
211
212/*
213 * Because this code is used in the kernel, we must not touch any floating point
214 * or specialized registers. This leaves the following registers:
215 *
216 * eax ; volatile, safe to use
217 * ebx ; PIC register, gcc error when used
218 * ecx ; volatile, safe to use
219 * edx ; volatile, safe to use
220 * esi ; non-volatile, otherwise safe to use
221 * edi ; non-volatile, otherwise safe to use
222 *
223 * Using any of the non volatile register causes a spill to stack which is almost
224 * certainly a net performance loss. Also, note that the array ref (__dtrace_args)
225 * consumes one free register. If all three of the volatile regs are used for load/store,
226 * the compiler will spill a register to hold the array ref.
227 *
228 * The end result is that we only pipeline two loads/stores at a time. Blech.
229 */
230
231#define DTRACE_CALL0ARGS(provider, name)							\
232	asm volatile (										\
233	              DTRACE_CALL(provider, name)						\
234	              "# eat trailing nl +tabfrom DTRACE_CALL"					\
235	              :										\
236	              :										\
237	);
238
239#define DTRACE_CALL1ARG(provider, name)								\
240	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
241	              "movl\t0x0(%0),%%eax"						"\n\t"	\
242	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
243	              DTRACE_CALL(provider, name)						\
244                      "addl\t$0x10,%%esp"							\
245	              :										\
246	              : "r" (__dtrace_args)		       					\
247	              : "memory", "eax"								\
248	);
249
250#define DTRACE_CALL2ARGS(provider, name)							\
251	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
252	              "movl\t0x0(%0),%%eax"						"\n\t"	\
253		      "movl\t0x4(%0),%%edx"						"\n\t"	\
254	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
255	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
256	              DTRACE_CALL(provider, name)						\
257                      "addl\t$0x10,%%esp"							\
258	              :										\
259	              : "r" (__dtrace_args)							\
260	              : "memory", "eax", "edx"							\
261	);
262
263#define DTRACE_CALL3ARGS(provider, name)							\
264	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
265	              "movl\t0x0(%0),%%eax"						"\n\t"	\
266		      "movl\t0x4(%0),%%edx"						"\n\t"	\
267	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
268	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
269	              "movl\t0x8(%0),%%eax"						"\n\t"	\
270	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
271	              DTRACE_CALL(provider, name)						\
272                      "addl\t$0x10,%%esp"							\
273	              :										\
274	              : "r" (__dtrace_args)							\
275	              : "memory", "eax", "edx"							\
276	);
277
278#define DTRACE_CALL4ARGS(provider, name)							\
279	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
280	              "movl\t0x0(%0),%%eax"						"\n\t"	\
281		      "movl\t0x4(%0),%%edx"						"\n\t"	\
282	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
283	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
284	              "movl\t0x8(%0),%%eax"						"\n\t"	\
285		      "movl\t0xC(%0),%%edx"						"\n\t"	\
286	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
287	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
288	              DTRACE_CALL(provider, name)						\
289                      "addl\t$0x10,%%esp"							\
290	              :										\
291	              : "r" (__dtrace_args)							\
292	              : "memory", "eax", "edx"	       						\
293	);
294
295#define DTRACE_CALL5ARGS(provider, name)							\
296	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
297	              "movl\t0x0(%0),%%eax"						"\n\t"	\
298		      "movl\t0x4(%0),%%edx"						"\n\t"	\
299	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
300	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
301	              "movl\t0x8(%0),%%eax"						"\n\t"	\
302		      "movl\t0xC(%0),%%edx"						"\n\t"	\
303	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
304	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
305	              "movl\t0x10(%0),%%eax"						"\n\t"	\
306	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
307	              DTRACE_CALL(provider, name)						\
308                      "addl\t$0x20,%%esp"							\
309	              :										\
310	              : "r" (__dtrace_args)							\
311	              : "memory", "eax", "edx"	       						\
312	);
313
314#define DTRACE_CALL6ARGS(provider, name)							\
315	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
316	              "movl\t0x0(%0),%%eax"						"\n\t"	\
317		      "movl\t0x4(%0),%%edx"						"\n\t"	\
318	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
319	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
320	              "movl\t0x8(%0),%%eax"						"\n\t"	\
321		      "movl\t0xC(%0),%%edx"						"\n\t"	\
322	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
323	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
324	              "movl\t0x10(%0),%%eax"						"\n\t"	\
325		      "movl\t0x14(%0),%%edx"						"\n\t"	\
326	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
327	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
328	              DTRACE_CALL(provider, name)						\
329                      "addl\t$0x20,%%esp"							\
330	              :										\
331	              : "r" (__dtrace_args)							\
332	              : "memory", "eax", "edx"	       						\
333	);
334
335#define DTRACE_CALL7ARGS(provider, name)							\
336	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
337	              "movl\t0x0(%0),%%eax"						"\n\t"	\
338		      "movl\t0x4(%0),%%edx"						"\n\t"	\
339	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
340	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
341	              "movl\t0x8(%0),%%eax"						"\n\t"	\
342		      "movl\t0xC(%0),%%edx"						"\n\t"	\
343	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
344	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
345	              "movl\t0x10(%0),%%eax"						"\n\t"	\
346		      "movl\t0x14(%0),%%edx"						"\n\t"	\
347	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
348	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
349	              "movl\t0x18(%0),%%eax"						"\n\t"	\
350	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
351	              DTRACE_CALL(provider, name)						\
352                      "addl\t$0x20,%%esp"							\
353	              :										\
354	              : "r" (__dtrace_args)							\
355	              : "memory", "eax", "edx"	       						\
356	);
357
358#define DTRACE_CALL8ARGS(provider, name)							\
359	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
360	              "movl\t0x0(%0),%%eax"						"\n\t"	\
361		      "movl\t0x4(%0),%%edx"						"\n\t"	\
362	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
363	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
364	              "movl\t0x8(%0),%%eax"						"\n\t"	\
365		      "movl\t0xC(%0),%%edx"						"\n\t"	\
366	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
367	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
368	              "movl\t0x10(%0),%%eax"						"\n\t"	\
369		      "movl\t0x14(%0),%%edx"						"\n\t"	\
370	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
371	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
372	              "movl\t0x18(%0),%%eax"						"\n\t"	\
373		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
374	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
375	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
376	              DTRACE_CALL(provider, name)						\
377                      "addl\t$0x20,%%esp"							\
378	              :										\
379	              : "r" (__dtrace_args)							\
380	              : "memory", "eax", "edx"	       						\
381	);
382
383#define DTRACE_CALL9ARGS(provider, name)							\
384	asm volatile ("subl\t$0x30,%%esp"						"\n\t"	\
385	              "movl\t0x0(%0),%%eax"						"\n\t"	\
386		      "movl\t0x4(%0),%%edx"						"\n\t"	\
387	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
388	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
389	              "movl\t0x8(%0),%%eax"						"\n\t"	\
390		      "movl\t0xC(%0),%%edx"						"\n\t"	\
391	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
392	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
393	              "movl\t0x10(%0),%%eax"						"\n\t"	\
394		      "movl\t0x14(%0),%%edx"						"\n\t"	\
395	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
396	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
397	              "movl\t0x18(%0),%%eax"						"\n\t"	\
398		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
399	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
400	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
401	              "movl\t0x20(%0),%%eax"						"\n\t"	\
402	              "movl\t%%eax,0x20(%%esp)"						"\n\t"	\
403	              DTRACE_CALL(provider, name)						\
404                      "addl\t$0x30,%%esp"							\
405	              :										\
406	              : "r" (__dtrace_args)							\
407	              : "memory", "eax", "edx"	       						\
408	);
409
410#define DTRACE_CALL10ARGS(provider, name)							\
411	asm volatile ("subl\t$0x30,%%esp"						"\n\t"	\
412	              "movl\t0x0(%0),%%eax"						"\n\t"	\
413		      "movl\t0x4(%0),%%edx"						"\n\t"	\
414	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
415	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
416	              "movl\t0x8(%0),%%eax"						"\n\t"	\
417		      "movl\t0xC(%0),%%edx"						"\n\t"	\
418	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
419	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
420	              "movl\t0x10(%0),%%eax"						"\n\t"	\
421		      "movl\t0x14(%0),%%edx"						"\n\t"	\
422	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
423	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
424	              "movl\t0x18(%0),%%eax"						"\n\t"	\
425		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
426	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
427	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
428	              "movl\t0x20(%0),%%eax"						"\n\t"	\
429		      "movl\t0x24(%0),%%edx"						"\n\t"	\
430	              "movl\t%%eax,0x20(%%esp)"						"\n\t"	\
431	              "movl\t%%edx,0x24(%%esp)"						"\n\t"	\
432	              DTRACE_CALL(provider, name)						\
433                      "addl\t$0x30,%%esp"							\
434	              :										\
435	              : "r" (__dtrace_args)							\
436	              : "memory", "eax", "edx"	       						\
437	);
438
439#endif // __i386__
440
441#endif	/* _MACH_I386_SDT_ISA_H */
442