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