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 do the symbol can be located
41 */
42#define DTRACE_LAB(p, n)		\
43   "__dtrace_probe$" DTRACE_TOSTRING(__LINE__) DTRACE_STRINGIFY(_##p##___##n)
44
45#define DTRACE_LABEL(p, n)		\
46      ".section __DATA, __data\n\t"	\
47      ".globl " DTRACE_LAB(p, n) "\n\t"	\
48       DTRACE_LAB(p, n) ":" ".long 1f""\n\t"	\
49       ".text" "\n\t"			\
50	"1:"
51#else	/* !KERNEL */
52#define DTRACE_LABEL(p, n)									\
53	"__dtrace_probe$" DTRACE_TOSTRING(__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":"	"\n\t"
54#endif	/* !KERNEL */
55
56#ifdef DTRACE_CALL_TEST
57
58#define DTRACE_CALL(p,n)	\
59	DTRACE_LABEL(p,n)	\
60	DTRACE_CALL_INSN(p,n)
61
62#else
63
64#define DTRACE_CALL(p,n)	\
65	DTRACE_LABEL(p,n)	\
66	DTRACE_NOPS
67
68#endif
69
70#ifdef __x86_64__
71
72#define DTRACE_NOPS			\
73	"nop"			"\n\t"	\
74	"leal 0(%%esi), %%esi"	"\n\t"
75
76#define DTRACE_CALL_INSN(p,n)						\
77	"call _dtracetest" DTRACE_STRINGIFY(_##p##_##n)	"\n\t"
78
79#define ARG1_EXTENT	1
80#define ARGS2_EXTENT	2
81#define ARGS3_EXTENT	3
82#define ARGS4_EXTENT	4
83#define ARGS5_EXTENT	5
84#define ARGS6_EXTENT	6
85#define ARGS7_EXTENT	7
86#define ARGS8_EXTENT	8
87#define ARGS9_EXTENT	10
88#define ARGS10_EXTENT	10
89
90#define DTRACE_CALL0ARGS(provider, name)							\
91	asm volatile (										\
92		      DTRACE_CALL(provider, name)						\
93	);
94
95#define DTRACE_CALL1ARG(provider, name)								\
96	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
97		      DTRACE_CALL(provider, name)						\
98	              :										\
99	              : "r" (__dtrace_args)							\
100	              : "memory", "rdi"									\
101	);
102
103#define DTRACE_CALL2ARGS(provider, name)							\
104	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
105	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
106		      DTRACE_CALL(provider, name)						\
107	              :										\
108	              : "r" (__dtrace_args)							\
109	              : "memory", "rdi", "rsi"								\
110	);
111
112#define DTRACE_CALL3ARGS(provider, name)							\
113	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
114	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
115	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
116		      DTRACE_CALL(provider, name)						\
117	              :										\
118	              : "r" (__dtrace_args)							\
119	              : "memory", "rdi", "rsi", "rdx"							\
120	);
121
122#define DTRACE_CALL4ARGS(provider, name)							\
123	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
124	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
125	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
126	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
127		      DTRACE_CALL(provider, name)						\
128	              :										\
129	              : "r" (__dtrace_args)							\
130	              : "memory", "rdi", "rsi", "rdx", "rcx"						\
131	);
132
133#define DTRACE_CALL5ARGS(provider, name)							\
134	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
135	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
136	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
137	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
138	              "movq\t0x20(%0),%%r8"						"\n\t"	\
139		      DTRACE_CALL(provider, name)						\
140	              :										\
141	              : "r" (__dtrace_args)							\
142	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8"					\
143	);
144
145#define DTRACE_CALL6ARGS(provider, name)							\
146	asm volatile ("movq\t0x0(%0),%%rdi"						"\n\t"	\
147	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
148	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
149	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
150	              "movq\t0x20(%0),%%r8"						"\n\t"	\
151	              "movq\t0x28(%0),%%r9"						"\n\t"	\
152		      DTRACE_CALL(provider, name)						\
153	              :										\
154	              : "r" (__dtrace_args)							\
155	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9"					\
156	);
157
158#define DTRACE_CALL7ARGS(provider, name)							\
159	asm volatile ("subq\t$0x8,%%rsp"						"\n\t"	\
160	              "movq\t0x0(%0),%%rdi"						"\n\t"	\
161	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
162	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
163	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
164	              "movq\t0x20(%0),%%r8"						"\n\t"	\
165	              "movq\t0x28(%0),%%r9"						"\n\t"	\
166	              "movq\t0x30(%0),%%rax"						"\n\t"	\
167	              "movq\t%%rax,0x0(%%rsp)"						"\n\t"	\
168		      DTRACE_CALL(provider, name)						\
169	              "addq\t$0x8,%%rsp"						"\n\t"	\
170	              :										\
171	              : "r" (__dtrace_args)							\
172	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "rax"				\
173	);
174
175#define DTRACE_CALL8ARGS(provider, name)							\
176	asm volatile ("subq\t$0x10,%%rsp"						"\n\t"	\
177	              "movq\t0x0(%0),%%rdi"						"\n\t"	\
178	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
179	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
180	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
181	              "movq\t0x20(%0),%%r8"						"\n\t"	\
182	              "movq\t0x28(%0),%%r9"						"\n\t"	\
183	              "movdqa\t0x30(%0),%%xmm1"						"\n\t"	\
184	              "movdqa\t%%xmm1,0x0(%%rsp)"					"\n\t"	\
185		      DTRACE_CALL(provider, name)						\
186	              "addq\t$0x10,%%rsp"						"\n\t"	\
187	              :										\
188	              : "r" (__dtrace_args)							\
189	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "xmm1"				\
190	);
191
192#define DTRACE_CALL9ARGS(provider, name)							\
193	DTRACE_CALL10ARGS(provider, name)
194
195#define DTRACE_CALL10ARGS(provider, name)							\
196	asm volatile ("subq\t$0x20,%%rsp"						"\n\t"	\
197	              "movq\t0x0(%0),%%rdi"						"\n\t"	\
198	              "movq\t0x8(%0),%%rsi"						"\n\t"	\
199	              "movq\t0x10(%0),%%rdx"						"\n\t"	\
200	              "movq\t0x18(%0),%%rcx"						"\n\t"	\
201	              "movq\t0x20(%0),%%r8"						"\n\t"	\
202	              "movq\t0x28(%0),%%r9"						"\n\t"	\
203	              "movdqa\t0x30(%0),%%xmm1"						"\n\t"	\
204	              "movdqa\t0x40(%0),%%xmm2"						"\n\t"	\
205	              "movdqa\t%%xmm1,0x0(%%rsp)"					"\n\t"	\
206	              "movdqa\t%%xmm2,0x10(%%rsp)"					"\n\t"	\
207	              DTRACE_CALL(provider, name)						\
208	              "addq\t$0x20,%%rsp"						"\n\t"	\
209	              :										\
210	              : "r" (__dtrace_args)							\
211	              : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "xmm1", "xmm2"			\
212	);
213
214#endif // __x86_64__
215
216#ifdef __i386__
217
218#define DTRACE_NOPS			\
219	"nop"			"\n\t"	\
220	"leal 0(%%esi), %%esi"	"\n\t"
221
222#define DTRACE_CALL_INSN(p,n)						\
223	"call _dtracetest" DTRACE_STRINGIFY(_##p##_##n)	"\n\t"
224
225#define ARG1_EXTENT	1
226#define ARGS2_EXTENT	2
227#define ARGS3_EXTENT	4
228#define ARGS4_EXTENT	4
229#define ARGS5_EXTENT	8
230#define ARGS6_EXTENT	8
231#define ARGS7_EXTENT	8
232#define ARGS8_EXTENT	8
233#define ARGS9_EXTENT	12
234#define ARGS10_EXTENT	12
235
236/*
237 * Because this code is used in the kernel, we must not touch any floating point
238 * or specialized registers. This leaves the following registers:
239 *
240 * eax ; volatile, safe to use
241 * ebx ; PIC register, gcc error when used
242 * ecx ; volatile, safe to use
243 * edx ; volatile, safe to use
244 * esi ; non-volatile, otherwise safe to use
245 * edi ; non-volatile, otherwise safe to use
246 *
247 * Using any of the non volatile register causes a spill to stack which is almost
248 * certainly a net performance loss. Also, note that the array ref (__dtrace_args)
249 * consumes one free register. If all three of the volatile regs are used for load/store,
250 * the compiler will spill a register to hold the array ref.
251 *
252 * The end result is that we only pipeline two loads/stores at a time. Blech.
253 */
254
255#define DTRACE_CALL0ARGS(provider, name)							\
256	asm volatile (										\
257	              DTRACE_CALL(provider, name)						\
258	              "# eat trailing nl +tabfrom DTRACE_CALL"					\
259	              :										\
260	              :										\
261	);
262
263#define DTRACE_CALL1ARG(provider, name)								\
264	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
265	              "movl\t0x0(%0),%%eax"						"\n\t"	\
266	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
267	              DTRACE_CALL(provider, name)						\
268                      "addl\t$0x10,%%esp"							\
269	              :										\
270	              : "r" (__dtrace_args)		       					\
271	              : "memory", "eax"									\
272	);
273
274#define DTRACE_CALL2ARGS(provider, name)							\
275	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
276	              "movl\t0x0(%0),%%eax"						"\n\t"	\
277		      "movl\t0x4(%0),%%edx"						"\n\t"	\
278	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
279	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
280	              DTRACE_CALL(provider, name)						\
281                      "addl\t$0x10,%%esp"							\
282	              :										\
283	              : "r" (__dtrace_args)							\
284	              : "memory", "eax", "edx"								\
285	);
286
287#define DTRACE_CALL3ARGS(provider, name)							\
288	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
289	              "movl\t0x0(%0),%%eax"						"\n\t"	\
290		      "movl\t0x4(%0),%%edx"						"\n\t"	\
291	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
292	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
293	              "movl\t0x8(%0),%%eax"						"\n\t"	\
294	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
295	              DTRACE_CALL(provider, name)						\
296                      "addl\t$0x10,%%esp"							\
297	              :										\
298	              : "r" (__dtrace_args)							\
299	              : "memory", "eax", "edx"								\
300	);
301
302#define DTRACE_CALL4ARGS(provider, name)							\
303	asm volatile ("subl\t$0x10,%%esp"						"\n\t"	\
304	              "movl\t0x0(%0),%%eax"						"\n\t"	\
305		      "movl\t0x4(%0),%%edx"						"\n\t"	\
306	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
307	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
308	              "movl\t0x8(%0),%%eax"						"\n\t"	\
309		      "movl\t0xC(%0),%%edx"						"\n\t"	\
310	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
311	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
312	              DTRACE_CALL(provider, name)						\
313                      "addl\t$0x10,%%esp"							\
314	              :										\
315	              : "r" (__dtrace_args)							\
316	              : "memory", "eax", "edx"	       							\
317	);
318
319#define DTRACE_CALL5ARGS(provider, name)							\
320	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
321	              "movl\t0x0(%0),%%eax"						"\n\t"	\
322		      "movl\t0x4(%0),%%edx"						"\n\t"	\
323	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
324	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
325	              "movl\t0x8(%0),%%eax"						"\n\t"	\
326		      "movl\t0xC(%0),%%edx"						"\n\t"	\
327	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
328	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
329	              "movl\t0x10(%0),%%eax"						"\n\t"	\
330	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
331	              DTRACE_CALL(provider, name)						\
332                      "addl\t$0x20,%%esp"							\
333	              :										\
334	              : "r" (__dtrace_args)							\
335	              : "memory", "eax", "edx"	       							\
336	);
337
338#define DTRACE_CALL6ARGS(provider, name)							\
339	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
340	              "movl\t0x0(%0),%%eax"						"\n\t"	\
341		      "movl\t0x4(%0),%%edx"						"\n\t"	\
342	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
343	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
344	              "movl\t0x8(%0),%%eax"						"\n\t"	\
345		      "movl\t0xC(%0),%%edx"						"\n\t"	\
346	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
347	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
348	              "movl\t0x10(%0),%%eax"						"\n\t"	\
349		      "movl\t0x14(%0),%%edx"						"\n\t"	\
350	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
351	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
352	              DTRACE_CALL(provider, name)						\
353                      "addl\t$0x20,%%esp"							\
354	              :										\
355	              : "r" (__dtrace_args)							\
356	              : "memory", "eax", "edx"	       							\
357	);
358
359#define DTRACE_CALL7ARGS(provider, name)							\
360	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
361	              "movl\t0x0(%0),%%eax"						"\n\t"	\
362		      "movl\t0x4(%0),%%edx"						"\n\t"	\
363	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
364	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
365	              "movl\t0x8(%0),%%eax"						"\n\t"	\
366		      "movl\t0xC(%0),%%edx"						"\n\t"	\
367	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
368	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
369	              "movl\t0x10(%0),%%eax"						"\n\t"	\
370		      "movl\t0x14(%0),%%edx"						"\n\t"	\
371	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
372	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
373	              "movl\t0x18(%0),%%eax"						"\n\t"	\
374	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
375	              DTRACE_CALL(provider, name)						\
376                      "addl\t$0x20,%%esp"							\
377	              :										\
378	              : "r" (__dtrace_args)							\
379	              : "memory", "eax", "edx"	       							\
380	);
381
382#define DTRACE_CALL8ARGS(provider, name)							\
383	asm volatile ("subl\t$0x20,%%esp"						"\n\t"	\
384	              "movl\t0x0(%0),%%eax"						"\n\t"	\
385		      "movl\t0x4(%0),%%edx"						"\n\t"	\
386	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
387	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
388	              "movl\t0x8(%0),%%eax"						"\n\t"	\
389		      "movl\t0xC(%0),%%edx"						"\n\t"	\
390	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
391	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
392	              "movl\t0x10(%0),%%eax"						"\n\t"	\
393		      "movl\t0x14(%0),%%edx"						"\n\t"	\
394	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
395	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
396	              "movl\t0x18(%0),%%eax"						"\n\t"	\
397		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
398	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
399	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
400	              DTRACE_CALL(provider, name)						\
401                      "addl\t$0x20,%%esp"							\
402	              :										\
403	              : "r" (__dtrace_args)							\
404	              : "memory", "eax", "edx"	       							\
405	);
406
407#define DTRACE_CALL9ARGS(provider, name)							\
408	asm volatile ("subl\t$0x30,%%esp"						"\n\t"	\
409	              "movl\t0x0(%0),%%eax"						"\n\t"	\
410		      "movl\t0x4(%0),%%edx"						"\n\t"	\
411	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
412	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
413	              "movl\t0x8(%0),%%eax"						"\n\t"	\
414		      "movl\t0xC(%0),%%edx"						"\n\t"	\
415	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
416	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
417	              "movl\t0x10(%0),%%eax"						"\n\t"	\
418		      "movl\t0x14(%0),%%edx"						"\n\t"	\
419	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
420	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
421	              "movl\t0x18(%0),%%eax"						"\n\t"	\
422		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
423	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
424	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
425	              "movl\t0x20(%0),%%eax"						"\n\t"	\
426	              "movl\t%%eax,0x20(%%esp)"						"\n\t"	\
427	              DTRACE_CALL(provider, name)						\
428                      "addl\t$0x30,%%esp"							\
429	              :										\
430	              : "r" (__dtrace_args)							\
431	              : "memory", "eax", "edx"	       							\
432	);
433
434#define DTRACE_CALL10ARGS(provider, name)							\
435	asm volatile ("subl\t$0x30,%%esp"						"\n\t"	\
436	              "movl\t0x0(%0),%%eax"						"\n\t"	\
437		      "movl\t0x4(%0),%%edx"						"\n\t"	\
438	              "movl\t%%eax,0x0(%%esp)"						"\n\t"	\
439	              "movl\t%%edx,0x4(%%esp)"						"\n\t"	\
440	              "movl\t0x8(%0),%%eax"						"\n\t"	\
441		      "movl\t0xC(%0),%%edx"						"\n\t"	\
442	              "movl\t%%eax,0x8(%%esp)"						"\n\t"	\
443	              "movl\t%%edx,0xC(%%esp)"						"\n\t"	\
444	              "movl\t0x10(%0),%%eax"						"\n\t"	\
445		      "movl\t0x14(%0),%%edx"						"\n\t"	\
446	              "movl\t%%eax,0x10(%%esp)"						"\n\t"	\
447	              "movl\t%%edx,0x14(%%esp)"						"\n\t"	\
448	              "movl\t0x18(%0),%%eax"						"\n\t"	\
449		      "movl\t0x1C(%0),%%edx"						"\n\t"	\
450	              "movl\t%%eax,0x18(%%esp)"						"\n\t"	\
451	              "movl\t%%edx,0x1C(%%esp)"						"\n\t"	\
452	              "movl\t0x20(%0),%%eax"						"\n\t"	\
453		      "movl\t0x24(%0),%%edx"						"\n\t"	\
454	              "movl\t%%eax,0x20(%%esp)"						"\n\t"	\
455	              "movl\t%%edx,0x24(%%esp)"						"\n\t"	\
456	              DTRACE_CALL(provider, name)						\
457                      "addl\t$0x30,%%esp"							\
458	              :										\
459	              : "r" (__dtrace_args)							\
460	              : "memory", "eax", "edx"	       							\
461	);
462
463#endif // __i386__
464
465#endif	/* _MACH_I386_SDT_ISA_H */
466