1331722Seadler/*
2132332Smarcel * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
3132332Smarcel * All rights reserved.
4132332Smarcel *
5132332Smarcel * Redistribution and use in source and binary forms, with or without
6132332Smarcel * modification, are permitted provided that the following conditions
7132332Smarcel * are met:
8132332Smarcel * 1. Redistributions of source code must retain the above copyright
9132332Smarcel *    notice, this list of conditions and the following disclaimer.
10132332Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11132332Smarcel *    notice, this list of conditions and the following disclaimer in the
12132332Smarcel *    documentation and/or other materials provided with the distribution.
13132332Smarcel *
14132332Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15132332Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16132332Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17132332Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18132332Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19132332Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20132332Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21132332Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22132332Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23132332Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24132332Smarcel * SUCH DAMAGE.
25132332Smarcel */
26132332Smarcel
27132332Smarcel#include <sys/cdefs.h>
28132332Smarcel__FBSDID("$FreeBSD$");
29132332Smarcel
30181059Smarcel#include <sys/types.h>
31181059Smarcel#include <machine/npx.h>
32132332Smarcel#include <string.h>
33132332Smarcel#include <thread_db.h>
34132332Smarcel
35132332Smarcel#include "libpthread_db.h"
36132332Smarcel
37132332Smarcelstatic int has_xmm_regs;
38132332Smarcel
39132332Smarcelvoid
40132332Smarcelpt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
41132332Smarcel{
42132332Smarcel	memcpy(&uc->uc_mcontext.mc_fs, &r->r_fs, 18*4);
43132332Smarcel	uc->uc_mcontext.mc_gs = r->r_gs;
44132332Smarcel}
45132332Smarcel
46132332Smarcelvoid
47132332Smarcelpt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
48132332Smarcel{
49132332Smarcel	memcpy(&r->r_fs, &uc->uc_mcontext.mc_fs, 18*4);
50132332Smarcel	r->r_gs = uc->uc_mcontext.mc_gs;
51132332Smarcel}
52132332Smarcel
53132332Smarcelvoid
54132332Smarcelpt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
55132332Smarcel{
56132332Smarcel	if (!has_xmm_regs)
57132332Smarcel		memcpy(&uc->uc_mcontext.mc_fpstate, r,
58132332Smarcel			sizeof(struct save87));
59132332Smarcel	else {
60132332Smarcel		int i;
61132332Smarcel		struct savexmm *sx = (struct savexmm *)&uc->uc_mcontext.mc_fpstate;
62132332Smarcel		memcpy(&sx->sv_env, &r->fpr_env, sizeof(r->fpr_env));
63132332Smarcel		for (i = 0; i < 8; ++i)
64132332Smarcel			memcpy(&sx->sv_fp[i].fp_acc, &r->fpr_acc[i], 10);
65132332Smarcel	}
66132332Smarcel}
67132332Smarcel
68132332Smarcelvoid
69132332Smarcelpt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
70132332Smarcel{
71132332Smarcel	if (!has_xmm_regs)
72132332Smarcel		memcpy(r, &uc->uc_mcontext.mc_fpstate, sizeof(struct save87));
73132332Smarcel	else {
74132332Smarcel		int i;
75277801Sdim		const struct savexmm *sx = (const struct savexmm *)&uc->uc_mcontext.mc_fpstate;
76132332Smarcel		memcpy(&r->fpr_env, &sx->sv_env, sizeof(r->fpr_env));
77132332Smarcel		for (i = 0; i < 8; ++i)
78132332Smarcel			memcpy(&r->fpr_acc[i], &sx->sv_fp[i].fp_acc, 10);
79132332Smarcel	}
80132332Smarcel}
81132332Smarcel
82132332Smarcelvoid
83146818Sdfrpt_fxsave_to_ucontext(const char* r, ucontext_t *uc)
84146818Sdfr{
85146818Sdfr	if (has_xmm_regs)
86146818Sdfr		memcpy(&uc->uc_mcontext.mc_fpstate, r, sizeof(struct savexmm));
87146818Sdfr}
88146818Sdfr
89146818Sdfrvoid
90146818Sdfrpt_ucontext_to_fxsave(const ucontext_t *uc, char *r)
91146818Sdfr{
92146818Sdfr	if (has_xmm_regs)
93146818Sdfr		memcpy(r, &uc->uc_mcontext.mc_fpstate, sizeof(struct savexmm));
94146818Sdfr}
95146818Sdfr
96146818Sdfrvoid
97132332Smarcelpt_md_init(void)
98132332Smarcel{
99132332Smarcel	ucontext_t uc;
100132332Smarcel
101132332Smarcel	getcontext(&uc);
102132332Smarcel	if (uc.uc_mcontext.mc_fpformat == _MC_FPFMT_XMM)
103132332Smarcel	    has_xmm_regs = 1;
104132332Smarcel}
105132332Smarcel
106132332Smarcelint
107132332Smarcelpt_reg_sstep(struct reg *reg, int step)
108132332Smarcel{
109132332Smarcel	unsigned int old;
110132332Smarcel
111132332Smarcel	old = reg->r_eflags;
112132332Smarcel	if (step)
113132332Smarcel		reg->r_eflags |= 0x0100;
114132332Smarcel	else
115132332Smarcel		reg->r_eflags &= ~0x0100;
116132332Smarcel	return (old != reg->r_eflags); /* changed ? */
117132332Smarcel}
118132332Smarcel
119