1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#ifndef RLD
24#ifdef SHLIB
25#undef environ
26#endif
27
28#define __busy busy
29#define __c0 c0
30#define __c1 c1
31#define __c2 c2
32#define __c3 c3
33#define __cs cs
34#define __darwin_fp_control fp_control
35#define __darwin_fp_status fp_status
36#define __darwin_i386_exception_state i386_exception_state
37#define __darwin_i386_float_state i386_float_state
38#define __darwin_i386_thread_state i386_thread_state
39#define __darwin_mmst_reg mmst_reg
40#define __darwin_xmm_reg xmm_reg
41#define __denorm denorm
42#define __ds ds
43#define __eax eax
44#define __ebp ebp
45#define __ebx ebx
46#define __ecx ecx
47#define __edi edi
48#define __edx edx
49#define __eflags eflags
50#define __eip eip
51#define __err err
52#define __errsumm errsumm
53#define __es es
54#define __esi esi
55#define __esp esp
56#define __faultvaddr faultvaddr
57#define __fpu_cs fpu_cs
58#define __fpu_dp fpu_dp
59#define __fpu_ds fpu_ds
60#define __fpu_fcw fpu_fcw
61#define __fpu_fop fpu_fop
62#define __fpu_fsw fpu_fsw
63#define __fpu_ftw fpu_ftw
64#define __fpu_ip fpu_ip
65#define __fpu_mxcsr fpu_mxcsr
66#define __fpu_mxcsrmask fpu_mxcsrmask
67#define __fpu_reserved fpu_reserved
68#define __fpu_reserved1 fpu_reserved1
69#define __fpu_rsrv1 fpu_rsrv1
70#define __fpu_rsrv2 fpu_rsrv2
71#define __fpu_rsrv3 fpu_rsrv3
72#define __fpu_rsrv4 fpu_rsrv4
73#define __fpu_stmm0 fpu_stmm0
74#define __fpu_stmm1 fpu_stmm1
75#define __fpu_stmm2 fpu_stmm2
76#define __fpu_stmm3 fpu_stmm3
77#define __fpu_stmm4 fpu_stmm4
78#define __fpu_stmm5 fpu_stmm5
79#define __fpu_stmm6 fpu_stmm6
80#define __fpu_stmm7 fpu_stmm7
81#define __fpu_xmm0 fpu_xmm0
82#define __fpu_xmm1 fpu_xmm1
83#define __fpu_xmm2 fpu_xmm2
84#define __fpu_xmm3 fpu_xmm3
85#define __fpu_xmm4 fpu_xmm4
86#define __fpu_xmm5 fpu_xmm5
87#define __fpu_xmm6 fpu_xmm6
88#define __fpu_xmm7 fpu_xmm7
89#define __fs fs
90#define __gs gs
91#define __invalid invalid
92#define __mmst_reg mmst_reg
93#define __mmst_rsrv mmst_rsrv
94#define __ovrfl ovrfl
95#define __pc pc
96#define __precis precis
97#define __rc rc
98#define __ss ss
99#define __stkflt stkflt
100#define __tos tos
101#define __trapno trapno
102#define __undfl undfl
103#define __xmm_reg xmm_reg
104#define __zdiv zdiv
105
106#define __rax rax
107#define __rbx rbx
108#define __rcx rcx
109#define __rdx rdx
110#define __rdi rdi
111#define __rsi rsi
112#define __rbp rbp
113#define __rsp rsp
114#define __r8 r8
115#define __r9 r9
116#define __r10 r10
117#define __r11 r11
118#define __r12 r12
119#define __r13 r13
120#define __r14 r14
121#define __r15 r15
122#define __rip rip
123#define __rflags rflags
124
125#define __dr0 dr0
126#define __dr1 dr1
127#define __dr2 dr2
128#define __dr3 dr3
129#define __dr4 dr4
130#define __dr5 dr5
131#define __dr6 dr6
132#define __dr7 dr7
133
134#include <string.h>
135#include <libkern/OSByteOrder.h>
136#import <mach-o/i386/swap.h>
137
138void
139swap_i386_thread_state(
140i386_thread_state_t *cpu,
141enum NXByteOrder target_byte_sex)
142{
143	cpu->eax = OSSwapInt32(cpu->eax);
144	cpu->ebx = OSSwapInt32(cpu->ebx);
145	cpu->ecx = OSSwapInt32(cpu->ecx);
146	cpu->edx = OSSwapInt32(cpu->edx);
147	cpu->edi = OSSwapInt32(cpu->edi);
148	cpu->esi = OSSwapInt32(cpu->esi);
149	cpu->ebp = OSSwapInt32(cpu->ebp);
150	cpu->esp = OSSwapInt32(cpu->esp);
151	cpu->ss = OSSwapInt32(cpu->ss);
152	cpu->eflags = OSSwapInt32(cpu->eflags);
153	cpu->eip = OSSwapInt32(cpu->eip);
154	cpu->cs = OSSwapInt32(cpu->cs);
155	cpu->ds = OSSwapInt32(cpu->ds);
156	cpu->es = OSSwapInt32(cpu->es);
157	cpu->fs = OSSwapInt32(cpu->fs);
158	cpu->gs = OSSwapInt32(cpu->gs);
159}
160
161#ifdef x86_THREAD_STATE64
162void
163swap_x86_thread_state64(
164x86_thread_state64_t *cpu,
165enum NXByteOrder target_byte_sex)
166{
167	cpu->rax = OSSwapInt64(cpu->rax);
168	cpu->rbx = OSSwapInt64(cpu->rbx);
169	cpu->rcx = OSSwapInt64(cpu->rcx);
170	cpu->rdx = OSSwapInt64(cpu->rdx);
171	cpu->rdi = OSSwapInt64(cpu->rdi);
172	cpu->rsi = OSSwapInt64(cpu->rsi);
173	cpu->rbp = OSSwapInt64(cpu->rbp);
174	cpu->rsp = OSSwapInt64(cpu->rsp);
175	cpu->rflags = OSSwapInt64(cpu->rflags);
176	cpu->rip = OSSwapInt64(cpu->rip);
177	cpu->r8 = OSSwapInt64(cpu->r8);
178	cpu->r9 = OSSwapInt64(cpu->r9);
179	cpu->r10 = OSSwapInt64(cpu->r10);
180	cpu->r11 = OSSwapInt64(cpu->r11);
181	cpu->r12 = OSSwapInt64(cpu->r12);
182	cpu->r13 = OSSwapInt64(cpu->r13);
183	cpu->r14 = OSSwapInt64(cpu->r14);
184	cpu->r15 = OSSwapInt64(cpu->r15);
185	cpu->cs = OSSwapInt64(cpu->cs);
186	cpu->fs = OSSwapInt64(cpu->fs);
187	cpu->gs = OSSwapInt64(cpu->gs);
188}
189
190void
191swap_x86_state_hdr(
192x86_state_hdr_t *hdr,
193enum NXByteOrder target_byte_sex)
194{
195	hdr->flavor = OSSwapInt32(hdr->flavor);
196	hdr->count = OSSwapInt32(hdr->count);
197}
198
199void
200swap_x86_float_state64(
201x86_float_state64_t *fpu,
202enum NXByteOrder target_byte_sex)
203{
204    struct swapped_fp_control {
205	union {
206	    struct {
207		unsigned short
208			    :3,
209		    /*inf*/ :1,
210		    rc	    :2,
211		    pc	    :2,
212			    :2,
213		    precis  :1,
214		    undfl   :1,
215		    ovrfl   :1,
216		    zdiv    :1,
217		    denorm  :1,
218		    invalid :1;
219	    } fields;
220	    unsigned short half;
221	} u;
222    } sfpc;
223
224    struct swapped_fp_status {
225	union {
226	    struct {
227		unsigned short
228		    busy    :1,
229		    c3	    :1,
230		    tos	    :3,
231		    c2	    :1,
232		    c1	    :1,
233		    c0	    :1,
234		    errsumm :1,
235		    stkflt  :1,
236		    precis  :1,
237		    undfl   :1,
238		    ovrfl   :1,
239		    zdiv    :1,
240		    denorm  :1,
241		    invalid :1;
242	    } fields;
243	    unsigned short half;
244	} u;
245    } sfps;
246
247    enum NXByteOrder host_byte_sex;
248
249	host_byte_sex = NXHostByteOrder();
250
251	fpu->fpu_reserved[0] = OSSwapInt32(fpu->fpu_reserved[0]);
252	fpu->fpu_reserved[1] = OSSwapInt32(fpu->fpu_reserved[1]);
253
254	if(target_byte_sex == host_byte_sex){
255	    memcpy(&sfpc, &(fpu->fpu_fcw),
256		   sizeof(struct swapped_fp_control));
257	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
258	    fpu->fpu_fcw.rc = sfpc.u.fields.rc;
259	    fpu->fpu_fcw.pc = sfpc.u.fields.pc;
260	    fpu->fpu_fcw.precis = sfpc.u.fields.precis;
261	    fpu->fpu_fcw.undfl = sfpc.u.fields.undfl;
262	    fpu->fpu_fcw.ovrfl = sfpc.u.fields.ovrfl;
263	    fpu->fpu_fcw.zdiv = sfpc.u.fields.zdiv;
264	    fpu->fpu_fcw.denorm = sfpc.u.fields.denorm;
265	    fpu->fpu_fcw.invalid = sfpc.u.fields.invalid;
266
267	    memcpy(&sfps, &(fpu->fpu_fsw),
268		   sizeof(struct swapped_fp_status));
269	    sfps.u.half = OSSwapInt16(sfps.u.half);
270	    fpu->fpu_fsw.busy = sfps.u.fields.busy;
271	    fpu->fpu_fsw.c3 = sfps.u.fields.c3;
272	    fpu->fpu_fsw.tos = sfps.u.fields.tos;
273	    fpu->fpu_fsw.c2 = sfps.u.fields.c2;
274	    fpu->fpu_fsw.c1 = sfps.u.fields.c1;
275	    fpu->fpu_fsw.c0 = sfps.u.fields.c0;
276	    fpu->fpu_fsw.errsumm = sfps.u.fields.errsumm;
277	    fpu->fpu_fsw.stkflt = sfps.u.fields.stkflt;
278	    fpu->fpu_fsw.precis = sfps.u.fields.precis;
279	    fpu->fpu_fsw.undfl = sfps.u.fields.undfl;
280	    fpu->fpu_fsw.ovrfl = sfps.u.fields.ovrfl;
281	    fpu->fpu_fsw.zdiv = sfps.u.fields.zdiv;
282	    fpu->fpu_fsw.denorm = sfps.u.fields.denorm;
283	    fpu->fpu_fsw.invalid = sfps.u.fields.invalid;
284	}
285	else{
286	    sfpc.u.fields.rc = fpu->fpu_fcw.rc;
287	    sfpc.u.fields.pc = fpu->fpu_fcw.pc;
288	    sfpc.u.fields.precis = fpu->fpu_fcw.precis;
289	    sfpc.u.fields.undfl = fpu->fpu_fcw.undfl;
290	    sfpc.u.fields.ovrfl = fpu->fpu_fcw.ovrfl;
291	    sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv;
292	    sfpc.u.fields.denorm = fpu->fpu_fcw.denorm;
293	    sfpc.u.fields.invalid = fpu->fpu_fcw.invalid;
294	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
295	    memcpy(&(fpu->fpu_fcw), &sfpc,
296		   sizeof(struct swapped_fp_control));
297
298	    sfps.u.fields.busy = fpu->fpu_fsw.busy;
299	    sfps.u.fields.c3 = fpu->fpu_fsw.c3;
300	    sfps.u.fields.tos = fpu->fpu_fsw.tos;
301	    sfps.u.fields.c2 = fpu->fpu_fsw.c2;
302	    sfps.u.fields.c1 = fpu->fpu_fsw.c1;
303	    sfps.u.fields.c0 = fpu->fpu_fsw.c0;
304	    sfps.u.fields.errsumm = fpu->fpu_fsw.errsumm;
305	    sfps.u.fields.stkflt = fpu->fpu_fsw.stkflt;
306	    sfps.u.fields.precis = fpu->fpu_fsw.precis;
307	    sfps.u.fields.undfl = fpu->fpu_fsw.undfl;
308	    sfps.u.fields.ovrfl = fpu->fpu_fsw.ovrfl;
309	    sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv;
310	    sfps.u.fields.denorm = fpu->fpu_fsw.denorm;
311	    sfps.u.fields.invalid = fpu->fpu_fsw.invalid;
312	    sfps.u.half = OSSwapInt16(sfps.u.half);
313	    memcpy(&(fpu->fpu_fsw), &sfps,
314		   sizeof(struct swapped_fp_status));
315	}
316	fpu->fpu_fop = OSSwapInt16(fpu->fpu_fop);
317	fpu->fpu_ip = OSSwapInt32(fpu->fpu_ip);
318	fpu->fpu_cs = OSSwapInt16(fpu->fpu_cs);
319	fpu->fpu_rsrv2 = OSSwapInt16(fpu->fpu_rsrv2);
320	fpu->fpu_dp = OSSwapInt32(fpu->fpu_dp);
321	fpu->fpu_ds = OSSwapInt16(fpu->fpu_ds);
322	fpu->fpu_rsrv3 = OSSwapInt16(fpu->fpu_rsrv3);
323	fpu->fpu_mxcsr = OSSwapInt32(fpu->fpu_mxcsr);
324	fpu->fpu_mxcsrmask = OSSwapInt32(fpu->fpu_mxcsrmask);
325	fpu->fpu_reserved1 = OSSwapInt32(fpu->fpu_reserved1);
326}
327
328void
329swap_x86_exception_state64(
330x86_exception_state64_t *exc,
331enum NXByteOrder target_byte_sex)
332{
333	exc->trapno = OSSwapInt32(exc->trapno);
334	exc->err = OSSwapInt32(exc->err);
335    	exc->faultvaddr = OSSwapInt64(exc->faultvaddr);
336}
337
338void
339swap_x86_thread_state(
340x86_thread_state_t *cpu,
341enum NXByteOrder target_byte_sex)
342{
343    x86_state_hdr_t hdr;
344    enum NXByteOrder host_byte_sex;
345
346	host_byte_sex = NXHostByteOrder();
347	hdr = cpu->tsh;
348	if(target_byte_sex == host_byte_sex)
349	    swap_x86_state_hdr(&hdr, host_byte_sex);
350
351	swap_x86_state_hdr(&cpu->tsh, target_byte_sex);
352
353	if(hdr.flavor == x86_THREAD_STATE32)
354	    swap_i386_thread_state(&cpu->uts.ts32, target_byte_sex);
355	else if(hdr.flavor == x86_THREAD_STATE64)
356	    swap_x86_thread_state64(&cpu->uts.ts64, target_byte_sex);
357}
358
359void
360swap_x86_float_state(
361x86_float_state_t *fpu,
362enum NXByteOrder target_byte_sex)
363{
364    x86_state_hdr_t hdr;
365    enum NXByteOrder host_byte_sex;
366
367	host_byte_sex = NXHostByteOrder();
368	hdr = fpu->fsh;
369	if(target_byte_sex == host_byte_sex)
370	    swap_x86_state_hdr(&hdr, host_byte_sex);
371
372	swap_x86_state_hdr(&fpu->fsh, target_byte_sex);
373
374/* current i386 thread states */
375#if i386_THREAD_STATE == 1
376	if(hdr.flavor == x86_FLOAT_STATE32)
377	    swap_i386_float_state(&fpu->ufs.fs32, target_byte_sex);
378	else
379#endif
380	if(hdr.flavor == x86_FLOAT_STATE64)
381	    swap_x86_float_state64(&fpu->ufs.fs64, target_byte_sex);
382}
383
384void
385swap_x86_exception_state(
386x86_exception_state_t *exc,
387enum NXByteOrder target_byte_sex)
388{
389    x86_state_hdr_t hdr;
390    enum NXByteOrder host_byte_sex;
391
392	host_byte_sex = NXHostByteOrder();
393	hdr = exc->esh;
394	if(target_byte_sex == host_byte_sex)
395	    swap_x86_state_hdr(&hdr, host_byte_sex);
396
397	swap_x86_state_hdr(&exc->esh, target_byte_sex);
398
399/* current i386 thread states */
400#if i386_THREAD_STATE == 1
401	if(hdr.flavor == x86_EXCEPTION_STATE32)
402	    swap_i386_exception_state(&exc->ues.es32, target_byte_sex);
403	else
404#endif
405	if(hdr.flavor == x86_EXCEPTION_STATE64)
406	    swap_x86_exception_state64(&exc->ues.es64, target_byte_sex);
407}
408
409void
410swap_x86_debug_state32(
411x86_debug_state32_t *debug,
412enum NXByteOrder target_byte_sex)
413{
414	debug->dr0 = OSSwapInt32(debug->dr0);
415	debug->dr1 = OSSwapInt32(debug->dr1);
416	debug->dr2 = OSSwapInt32(debug->dr2);
417	debug->dr3 = OSSwapInt32(debug->dr3);
418	debug->dr4 = OSSwapInt32(debug->dr4);
419	debug->dr5 = OSSwapInt32(debug->dr5);
420	debug->dr6 = OSSwapInt32(debug->dr6);
421	debug->dr7 = OSSwapInt32(debug->dr7);
422}
423
424void
425swap_x86_debug_state64(
426x86_debug_state64_t *debug,
427enum NXByteOrder target_byte_sex)
428{
429	debug->dr0 = OSSwapInt64(debug->dr0);
430	debug->dr1 = OSSwapInt64(debug->dr1);
431	debug->dr2 = OSSwapInt64(debug->dr2);
432	debug->dr3 = OSSwapInt64(debug->dr3);
433	debug->dr4 = OSSwapInt64(debug->dr4);
434	debug->dr5 = OSSwapInt64(debug->dr5);
435	debug->dr6 = OSSwapInt64(debug->dr6);
436	debug->dr7 = OSSwapInt64(debug->dr7);
437}
438
439void
440swap_x86_debug_state(
441x86_debug_state_t *debug,
442enum NXByteOrder target_byte_sex)
443{
444    x86_state_hdr_t hdr;
445    enum NXByteOrder host_byte_sex;
446
447	host_byte_sex = NXHostByteOrder();
448	hdr = debug->dsh;
449	if(target_byte_sex == host_byte_sex)
450	    swap_x86_state_hdr(&hdr, host_byte_sex);
451
452	swap_x86_state_hdr(&debug->dsh, target_byte_sex);
453
454	if(hdr.flavor == x86_DEBUG_STATE32)
455	    swap_x86_debug_state32(&debug->uds.ds32, target_byte_sex);
456	else if(hdr.flavor == x86_DEBUG_STATE64)
457	    swap_x86_debug_state64(&debug->uds.ds64, target_byte_sex);
458}
459#endif /* x86_THREAD_STATE64 */
460
461/* current i386 thread states */
462#if i386_THREAD_STATE == 1
463void
464swap_i386_float_state(
465struct i386_float_state *fpu,
466enum NXByteOrder target_byte_sex)
467{
468#ifndef i386_EXCEPTION_STATE_COUNT
469    /* this routine does nothing as their are currently no non-byte fields */
470#else /* !defined(i386_EXCEPTION_STATE_COUNT) */
471    struct swapped_fp_control {
472	union {
473	    struct {
474		unsigned short
475			    :3,
476		    /*inf*/ :1,
477		    rc	    :2,
478		    pc	    :2,
479			    :2,
480		    precis  :1,
481		    undfl   :1,
482		    ovrfl   :1,
483		    zdiv    :1,
484		    denorm  :1,
485		    invalid :1;
486	    } fields;
487	    unsigned short half;
488	} u;
489    } sfpc;
490
491    struct swapped_fp_status {
492	union {
493	    struct {
494		unsigned short
495		    busy    :1,
496		    c3	    :1,
497		    tos	    :3,
498		    c2	    :1,
499		    c1	    :1,
500		    c0	    :1,
501		    errsumm :1,
502		    stkflt  :1,
503		    precis  :1,
504		    undfl   :1,
505		    ovrfl   :1,
506		    zdiv    :1,
507		    denorm  :1,
508		    invalid :1;
509	    } fields;
510	    unsigned short half;
511	} u;
512    } sfps;
513
514    enum NXByteOrder host_byte_sex;
515
516	host_byte_sex = NXHostByteOrder();
517
518	fpu->fpu_reserved[0] = OSSwapInt32(fpu->fpu_reserved[0]);
519	fpu->fpu_reserved[1] = OSSwapInt32(fpu->fpu_reserved[1]);
520
521	if(target_byte_sex == host_byte_sex){
522	    memcpy(&sfpc, &(fpu->fpu_fcw),
523		   sizeof(struct swapped_fp_control));
524	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
525	    fpu->fpu_fcw.rc = sfpc.u.fields.rc;
526	    fpu->fpu_fcw.pc = sfpc.u.fields.pc;
527	    fpu->fpu_fcw.precis = sfpc.u.fields.precis;
528	    fpu->fpu_fcw.undfl = sfpc.u.fields.undfl;
529	    fpu->fpu_fcw.ovrfl = sfpc.u.fields.ovrfl;
530	    fpu->fpu_fcw.zdiv = sfpc.u.fields.zdiv;
531	    fpu->fpu_fcw.denorm = sfpc.u.fields.denorm;
532	    fpu->fpu_fcw.invalid = sfpc.u.fields.invalid;
533
534	    memcpy(&sfps, &(fpu->fpu_fsw),
535		   sizeof(struct swapped_fp_status));
536	    sfps.u.half = OSSwapInt16(sfps.u.half);
537	    fpu->fpu_fsw.busy = sfps.u.fields.busy;
538	    fpu->fpu_fsw.c3 = sfps.u.fields.c3;
539	    fpu->fpu_fsw.tos = sfps.u.fields.tos;
540	    fpu->fpu_fsw.c2 = sfps.u.fields.c2;
541	    fpu->fpu_fsw.c1 = sfps.u.fields.c1;
542	    fpu->fpu_fsw.c0 = sfps.u.fields.c0;
543	    fpu->fpu_fsw.errsumm = sfps.u.fields.errsumm;
544	    fpu->fpu_fsw.stkflt = sfps.u.fields.stkflt;
545	    fpu->fpu_fsw.precis = sfps.u.fields.precis;
546	    fpu->fpu_fsw.undfl = sfps.u.fields.undfl;
547	    fpu->fpu_fsw.ovrfl = sfps.u.fields.ovrfl;
548	    fpu->fpu_fsw.zdiv = sfps.u.fields.zdiv;
549	    fpu->fpu_fsw.denorm = sfps.u.fields.denorm;
550	    fpu->fpu_fsw.invalid = sfps.u.fields.invalid;
551	}
552	else{
553	    sfpc.u.fields.rc = fpu->fpu_fcw.rc;
554	    sfpc.u.fields.pc = fpu->fpu_fcw.pc;
555	    sfpc.u.fields.precis = fpu->fpu_fcw.precis;
556	    sfpc.u.fields.undfl = fpu->fpu_fcw.undfl;
557	    sfpc.u.fields.ovrfl = fpu->fpu_fcw.ovrfl;
558	    sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv;
559	    sfpc.u.fields.denorm = fpu->fpu_fcw.denorm;
560	    sfpc.u.fields.invalid = fpu->fpu_fcw.invalid;
561	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
562	    memcpy(&(fpu->fpu_fcw), &sfpc,
563		   sizeof(struct swapped_fp_control));
564
565	    sfps.u.fields.busy = fpu->fpu_fsw.busy;
566	    sfps.u.fields.c3 = fpu->fpu_fsw.c3;
567	    sfps.u.fields.tos = fpu->fpu_fsw.tos;
568	    sfps.u.fields.c2 = fpu->fpu_fsw.c2;
569	    sfps.u.fields.c1 = fpu->fpu_fsw.c1;
570	    sfps.u.fields.c0 = fpu->fpu_fsw.c0;
571	    sfps.u.fields.errsumm = fpu->fpu_fsw.errsumm;
572	    sfps.u.fields.stkflt = fpu->fpu_fsw.stkflt;
573	    sfps.u.fields.precis = fpu->fpu_fsw.precis;
574	    sfps.u.fields.undfl = fpu->fpu_fsw.undfl;
575	    sfps.u.fields.ovrfl = fpu->fpu_fsw.ovrfl;
576	    sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv;
577	    sfps.u.fields.denorm = fpu->fpu_fsw.denorm;
578	    sfps.u.fields.invalid = fpu->fpu_fsw.invalid;
579	    sfps.u.half = OSSwapInt16(sfps.u.half);
580	    memcpy(&(fpu->fpu_fsw), &sfps,
581		   sizeof(struct swapped_fp_status));
582	}
583	fpu->fpu_fop = OSSwapInt16(fpu->fpu_fop);
584	fpu->fpu_ip = OSSwapInt32(fpu->fpu_ip);
585	fpu->fpu_cs = OSSwapInt16(fpu->fpu_cs);
586	fpu->fpu_rsrv2 = OSSwapInt16(fpu->fpu_rsrv2);
587	fpu->fpu_dp = OSSwapInt32(fpu->fpu_dp);
588	fpu->fpu_ds = OSSwapInt16(fpu->fpu_ds);
589	fpu->fpu_rsrv3 = OSSwapInt16(fpu->fpu_rsrv3);
590	fpu->fpu_mxcsr = OSSwapInt32(fpu->fpu_mxcsr);
591	fpu->fpu_mxcsrmask = OSSwapInt32(fpu->fpu_mxcsrmask);
592	fpu->fpu_reserved1 = OSSwapInt32(fpu->fpu_reserved1);
593
594#endif /* !defined(i386_EXCEPTION_STATE_COUNT) */
595}
596
597void
598swap_i386_exception_state(
599i386_exception_state_t *exc,
600enum NXByteOrder target_byte_sex)
601{
602	exc->trapno = OSSwapInt32(exc->trapno);
603	exc->err = OSSwapInt32(exc->err);
604    	exc->faultvaddr = OSSwapInt32(exc->faultvaddr);
605}
606#endif /* i386_THREAD_STATE == 1 */
607
608/* i386 thread states on older releases */
609#if i386_THREAD_STATE == -1
610void
611swap_i386_thread_fpstate(
612i386_thread_fpstate_t *fpu,
613enum NXByteOrder target_byte_sex)
614{
615    struct swapped_fp_control {
616	union {
617	    struct {
618		unsigned short
619			    :3,
620		    /*inf*/ :1,
621		    rc	    :2,
622		    pc	    :2,
623			    :2,
624		    precis  :1,
625		    undfl   :1,
626		    ovrfl   :1,
627		    zdiv    :1,
628		    denorm  :1,
629		    invalid :1;
630	    } fields;
631	    unsigned short half;
632	} u;
633    } sfpc;
634
635    struct swapped_fp_status {
636	union {
637	    struct {
638		unsigned short
639		    busy    :1,
640		    c3	    :1,
641		    tos	    :3,
642		    c2	    :1,
643		    c1	    :1,
644		    c0	    :1,
645		    errsumm :1,
646		    stkflt  :1,
647		    precis  :1,
648		    undfl   :1,
649		    ovrfl   :1,
650		    zdiv    :1,
651		    denorm  :1,
652		    invalid :1;
653	    } fields;
654	    unsigned short half;
655	} u;
656    } sfps;
657
658    struct swapped_fp_tag {
659	union {
660	    struct {
661		unsigned short
662		    tag7 :2,
663		    tag6 :2,
664		    tag5 :2,
665		    tag4 :2,
666		    tag3 :2,
667		    tag2 :2,
668		    tag1 :2,
669		    tag0 :2;
670	    } fields;
671	    unsigned short half;
672	} u;
673    } sfpt;
674
675    struct swapped_fp_data_reg {
676	unsigned short mant;
677	unsigned short mant1 :16,
678		       mant2 :16,
679		       mant3 :16;
680	union {
681	    struct {
682		unsigned short sign :1,
683			       exp  :15;
684	    } fields;
685	    unsigned short half;
686	} u;
687    } sfpd;
688
689    struct swapped_sel {
690	union {
691	    struct {
692    		unsigned short
693		    index :13,
694		    ti    :1,
695		    rpl   :2;
696	    } fields;
697	    unsigned short half;
698	} u;
699    } ss;
700
701    enum NXByteOrder host_byte_sex;
702    int i;
703
704	host_byte_sex = NXHostByteOrder();
705
706	fpu->environ.ip = OSSwapInt32(fpu->environ.ip);
707	fpu->environ.opcode = OSSwapInt16(fpu->environ.opcode);
708	fpu->environ.dp = OSSwapInt32(fpu->environ.dp);
709
710	if(target_byte_sex == host_byte_sex){
711	    memcpy(&sfpc, &(fpu->environ.control),
712		   sizeof(struct swapped_fp_control));
713	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
714	    fpu->environ.control.rc = sfpc.u.fields.rc;
715	    fpu->environ.control.pc = sfpc.u.fields.pc;
716	    fpu->environ.control.precis = sfpc.u.fields.precis;
717	    fpu->environ.control.undfl = sfpc.u.fields.undfl;
718	    fpu->environ.control.ovrfl = sfpc.u.fields.ovrfl;
719	    fpu->environ.control.zdiv = sfpc.u.fields.zdiv;
720	    fpu->environ.control.denorm = sfpc.u.fields.denorm;
721	    fpu->environ.control.invalid = sfpc.u.fields.invalid;
722
723	    memcpy(&sfps, &(fpu->environ.status),
724		   sizeof(struct swapped_fp_status));
725	    sfps.u.half = OSSwapInt16(sfps.u.half);
726	    fpu->environ.status.busy = sfps.u.fields.busy;
727	    fpu->environ.status.c3 = sfps.u.fields.c3;
728	    fpu->environ.status.tos = sfps.u.fields.tos;
729	    fpu->environ.status.c2 = sfps.u.fields.c2;
730	    fpu->environ.status.c1 = sfps.u.fields.c1;
731	    fpu->environ.status.c0 = sfps.u.fields.c0;
732	    fpu->environ.status.errsumm = sfps.u.fields.errsumm;
733	    fpu->environ.status.stkflt = sfps.u.fields.stkflt;
734	    fpu->environ.status.precis = sfps.u.fields.precis;
735	    fpu->environ.status.undfl = sfps.u.fields.undfl;
736	    fpu->environ.status.ovrfl = sfps.u.fields.ovrfl;
737	    fpu->environ.status.zdiv = sfps.u.fields.zdiv;
738	    fpu->environ.status.denorm = sfps.u.fields.denorm;
739	    fpu->environ.status.invalid = sfps.u.fields.invalid;
740
741	    memcpy(&sfpt, &(fpu->environ.tag),
742		   sizeof(struct swapped_fp_tag));
743	    sfpt.u.half = OSSwapInt16(sfpt.u.half);
744	    fpu->environ.tag.tag7 = sfpt.u.fields.tag7;
745	    fpu->environ.tag.tag6 = sfpt.u.fields.tag6;
746	    fpu->environ.tag.tag5 = sfpt.u.fields.tag5;
747	    fpu->environ.tag.tag4 = sfpt.u.fields.tag4;
748	    fpu->environ.tag.tag3 = sfpt.u.fields.tag3;
749	    fpu->environ.tag.tag2 = sfpt.u.fields.tag2;
750	    fpu->environ.tag.tag1 = sfpt.u.fields.tag1;
751	    fpu->environ.tag.tag0 = sfpt.u.fields.tag0;
752
753	    memcpy(&ss, &(fpu->environ.cs),
754		   sizeof(struct swapped_sel));
755	    ss.u.half = OSSwapInt16(ss.u.half);
756	    fpu->environ.cs.index = ss.u.fields.index;
757	    fpu->environ.cs.ti = ss.u.fields.ti;
758	    fpu->environ.cs.rpl = ss.u.fields.rpl;
759
760	    memcpy(&ss, &(fpu->environ.ds),
761		   sizeof(struct swapped_sel));
762	    ss.u.half = OSSwapInt16(ss.u.half);
763	    fpu->environ.ds.index = ss.u.fields.index;
764	    fpu->environ.ds.ti = ss.u.fields.ti;
765	    fpu->environ.ds.rpl = ss.u.fields.rpl;
766
767	    for(i = 0; i < 8; i++){
768		memcpy(&sfpd, &(fpu->stack.ST[i]),
769		       sizeof(struct swapped_fp_data_reg));
770		fpu->stack.ST[i].mant = OSSwapInt16(sfpd.mant);
771		fpu->stack.ST[i].mant1 = OSSwapInt16(sfpd.mant1);
772		fpu->stack.ST[i].mant2 = OSSwapInt16(sfpd.mant2);
773		fpu->stack.ST[i].mant3 = OSSwapInt16(sfpd.mant3);
774		sfpd.u.half = OSSwapInt16(sfpd.u.half);
775		fpu->stack.ST[i].exp = sfpd.u.fields.exp;
776		fpu->stack.ST[i].sign = sfpd.u.fields.sign;
777	    }
778	}
779	else{
780	    sfpc.u.fields.rc = fpu->environ.control.rc;
781	    sfpc.u.fields.pc = fpu->environ.control.pc;
782	    sfpc.u.fields.precis = fpu->environ.control.precis;
783	    sfpc.u.fields.undfl = fpu->environ.control.undfl;
784	    sfpc.u.fields.ovrfl = fpu->environ.control.ovrfl;
785	    sfpc.u.fields.zdiv = fpu->environ.control.zdiv;
786	    sfpc.u.fields.denorm = fpu->environ.control.denorm;
787	    sfpc.u.fields.invalid = fpu->environ.control.invalid;
788	    sfpc.u.half = OSSwapInt16(sfpc.u.half);
789	    memcpy(&(fpu->environ.control), &sfpc,
790		   sizeof(struct swapped_fp_control));
791
792	    sfps.u.fields.busy = fpu->environ.status.busy;
793	    sfps.u.fields.c3 = fpu->environ.status.c3;
794	    sfps.u.fields.tos = fpu->environ.status.tos;
795	    sfps.u.fields.c2 = fpu->environ.status.c2;
796	    sfps.u.fields.c1 = fpu->environ.status.c1;
797	    sfps.u.fields.c0 = fpu->environ.status.c0;
798	    sfps.u.fields.errsumm = fpu->environ.status.errsumm;
799	    sfps.u.fields.stkflt = fpu->environ.status.stkflt;
800	    sfps.u.fields.precis = fpu->environ.status.precis;
801	    sfps.u.fields.undfl = fpu->environ.status.undfl;
802	    sfps.u.fields.ovrfl = fpu->environ.status.ovrfl;
803	    sfps.u.fields.zdiv = fpu->environ.status.zdiv;
804	    sfps.u.fields.denorm = fpu->environ.status.denorm;
805	    sfps.u.fields.invalid = fpu->environ.status.invalid;
806	    sfps.u.half = OSSwapInt16(sfps.u.half);
807	    memcpy(&(fpu->environ.status), &sfps,
808		   sizeof(struct swapped_fp_status));
809
810	    sfpt.u.fields.tag7 = fpu->environ.tag.tag7;
811	    sfpt.u.fields.tag6 = fpu->environ.tag.tag6;
812	    sfpt.u.fields.tag5 = fpu->environ.tag.tag5;
813	    sfpt.u.fields.tag4 = fpu->environ.tag.tag4;
814	    sfpt.u.fields.tag3 = fpu->environ.tag.tag3;
815	    sfpt.u.fields.tag2 = fpu->environ.tag.tag2;
816	    sfpt.u.fields.tag1 = fpu->environ.tag.tag1;
817	    sfpt.u.fields.tag0 = fpu->environ.tag.tag0;
818	    sfpt.u.half = OSSwapInt16(sfpt.u.half);
819	    memcpy(&(fpu->environ.tag), &sfpt,
820		   sizeof(struct swapped_fp_tag));
821
822	    ss.u.fields.index = fpu->environ.cs.index;
823	    ss.u.fields.ti = fpu->environ.cs.ti;
824	    ss.u.fields.rpl = fpu->environ.cs.rpl;
825	    ss.u.half = OSSwapInt16(ss.u.half);
826	    memcpy(&(fpu->environ.cs), &ss,
827		   sizeof(struct swapped_sel));
828
829	    ss.u.fields.index = fpu->environ.ds.index;
830	    ss.u.fields.ti = fpu->environ.ds.ti;
831	    ss.u.fields.rpl = fpu->environ.ds.rpl;
832	    ss.u.half = OSSwapInt16(ss.u.half);
833	    memcpy(&(fpu->environ.cs), &ss,
834		   sizeof(struct swapped_sel));
835
836	    for(i = 0; i < 8; i++){
837		sfpd.mant = OSSwapInt16(fpu->stack.ST[i].mant);
838		sfpd.mant1 = OSSwapInt16(fpu->stack.ST[i].mant1);
839		sfpd.mant2 = OSSwapInt16(fpu->stack.ST[i].mant2);
840		sfpd.mant3 = OSSwapInt16(fpu->stack.ST[i].mant3);
841		sfpd.u.fields.exp = fpu->stack.ST[i].exp;
842		sfpd.u.fields.sign = fpu->stack.ST[i].sign;
843		sfpd.u.half = OSSwapInt16(sfpd.u.half);
844		memcpy(&(fpu->stack.ST[i]), &sfpd,
845		       sizeof(struct swapped_fp_data_reg));
846	    }
847	}
848}
849
850void
851swap_i386_thread_exceptstate(
852i386_thread_exceptstate_t *exc,
853enum NXByteOrder target_byte_sex)
854{
855    struct swapped_err_code {
856	union {
857	    struct err_code_normal {
858		unsigned int		:16,
859				index	:13,
860				tbl	:2,
861				ext	:1;
862	    } normal;
863	    struct err_code_pgfault {
864		unsigned int		:29,
865				user	:1,
866				wrtflt	:1,
867				prot	:1;
868	    } pgfault;
869	    uint32_t word;
870	} u;
871    } sec;
872    uint32_t word;
873    enum NXByteOrder host_byte_sex;
874
875	host_byte_sex = NXHostByteOrder();
876
877	exc->trapno = OSSwapInt32(exc->trapno);
878	if(exc->trapno == 14){
879	    if(target_byte_sex == host_byte_sex){
880		memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code));
881		sec.u.word = OSSwapInt32(sec.u.word);
882		exc->err.pgfault.user   = sec.u.pgfault.user;
883		exc->err.pgfault.wrtflt = sec.u.pgfault.wrtflt;
884		exc->err.pgfault.prot   = sec.u.pgfault.prot;
885	    }
886	    else{
887		sec.u.pgfault.prot   = exc->err.pgfault.prot;
888		sec.u.pgfault.wrtflt = exc->err.pgfault.wrtflt;
889		sec.u.pgfault.user   = exc->err.pgfault.user;
890		sec.u.word = OSSwapInt32(sec.u.word);
891		memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code));
892	    }
893	}
894	else{
895	    if(target_byte_sex == host_byte_sex){
896		memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code));
897		sec.u.word = OSSwapInt32(sec.u.word);
898		word = sec.u.normal.index;
899		exc->err.normal.index = OSSwapInt32(word);
900		exc->err.normal.tbl   = sec.u.normal.tbl;
901		exc->err.normal.ext   = sec.u.normal.ext;
902	    }
903	    else{
904		sec.u.normal.ext   = exc->err.normal.ext;
905		sec.u.normal.tbl   = exc->err.normal.tbl;
906		word = exc->err.normal.index;
907		sec.u.normal.index = OSSwapInt32(word);
908		sec.u.word = OSSwapInt32(sec.u.word);
909		memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code));
910	    }
911	}
912}
913
914void
915swap_i386_thread_cthreadstate(
916i386_thread_cthreadstate_t *user,
917enum NXByteOrder target_byte_sex)
918{
919	user->self = OSSwapInt32(user->self);
920}
921#endif /* i386_THREAD_STATE == -1 */
922#endif /* !defined(RLD) */
923