⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc_tools.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
字号:
/*        ppc_tools.c - necessary ppc definition for skyeye debugger        Copyright (C) 2003 Skyeye Develop Group        for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>        This program is free software; you can redistribute it and/or modify        it under the terms of the GNU General Public License as published by        the Free Software Foundation; either version 2 of the License, or        (at your option) any later version.        This program is distributed in the hope that it will be useful,        but WITHOUT ANY WARRANTY; without even the implied warranty of        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        GNU General Public License for more details.        You should have received a copy of the GNU General Public License        along with this program; if not, write to the Free Software        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * 12/21/2006   Michael.Kang  <blackfin.kang@gmail.com> */#include "types.h"#include "ppc_fpu.h"#include "ppc_cpu.h"extern PPC_CPU_State gCPU;int ppc_count_leading_zeros(uint64 i){	int ret;	uint32 dd = i >> 32;	if (dd) {		ret = 31;		if (dd > 0xffff) { ret -= 16; dd >>= 16; }		if (dd > 0xff) { ret -= 8; dd >>= 8; }		if (dd & 0xf0) { ret -= 4; dd >>= 4; }		if (dd & 0xc) { ret -= 2; dd >>= 2; }		if (dd & 0x2) ret--;	} else {		dd = (uint32)i;		ret = 63;		if (dd > 0xffff) { ret -= 16; dd >>= 16; }		if (dd > 0xff) { ret -= 8; dd >>= 8; }		if (dd & 0xf0) { ret -= 4; dd >>= 4; }		if (dd & 0xc) { ret -= 2; dd >>= 2; }		if (dd & 0x2) ret--;	}	return ret;}int ppc_fpu_normalize_quadro(ppc_quadro *d){	int ret = d->m0 ? ppc_count_leading_zeros(d->m0) : 64 + ppc_count_leading_zeros(d->m1);	return ret;}int ppc_fpu_normalize(ppc_double *d){	return ppc_count_leading_zeros(d->m);}int ppc_fpu_normalize_single(ppc_single *s){	int ret;	uint32 dd = s->m;	ret = 31;	if (dd > 0xffff) { ret -= 16; dd >>= 16; }	if (dd > 0xff) { ret -= 8; dd >>= 8; }	if (dd & 0xf0) { ret -= 4; dd >>= 4; }	if (dd & 0xc) { ret -= 2; dd >>= 2; }	if (dd & 0x2) ret--;	return ret;}//#include "tools/snprintf.h"void ppc_fpu_unpack_double(ppc_double *res, uint64 d){	FPD_UNPACK_VAR(d, res->s, res->e, res->m);//	ht_printf("ud: %qx: s:%d e:%d m:%qx\n", d, res.s, res.e, res.m);	// .124	if (res->e == 2047) {		if (res->m == 0) {			res->type = ppc_fpr_Inf;		} else {			res->type = ppc_fpr_NaN;		}	} else if (res->e == 0) {		if (res->m == 0) {			res->type = ppc_fpr_zero;		} else {			// normalize denormalized exponent			int diff = ppc_fpu_normalize(res) - 8;			res->m <<= diff+3;			res->e -= 1023 - 1 + diff;			res->type = ppc_fpr_norm;		}	} else {		res->e -= 1023; // unbias exponent		res->type = ppc_fpr_norm;		// add implied bit		res->m |= 1ULL<<52;		res->m <<= 3;	}//	ht_printf("ud: %qx: s:%d e:%d m:%qx\n", d, res.s, res.e, res.m);}void ppc_fpu_unpack_single(ppc_single *res, uint32 d){	FPS_UNPACK_VAR(d, res->s, res->e, res->m);	// .124	if (res->e == 255) {		if (res->m == 0) {			res->type = ppc_fpr_Inf;		} else {			res->type = ppc_fpr_NaN;		}	} else if (res->e == 0) {		if (res->m == 0) {			res->type = ppc_fpr_zero;		} else {			// normalize denormalized exponent			int diff = ppc_fpu_normalize_single(res) - 8;			res->m <<= diff+3;			res->e -= 127 - 1 + diff;			res->type = ppc_fpr_norm;		}	} else {		res->e -= 127; // unbias exponent		res->type = ppc_fpr_norm;		// add implied bit		res->m |= 1<<23;		res->m <<= 3;	}}uint32 ppc_fpu_round(ppc_double *d) {	// .132	switch (FPSCR_RN(gCPU.fpscr)) {	case FPSCR_RN_NEAR:		if (d->m & 0x7) {			if ((d->m & 0x7) != 4) {				d->m += 4;			} else if (d->m & 8) {				d->m += 4;			}			return FPSCR_XX;		}		return 0;	case FPSCR_RN_ZERO:		if (d->m & 0x7) {			return FPSCR_XX;		}		return 0;	case FPSCR_RN_PINF:		if (!d->s && (d->m & 0x7)) {			d->m += 8;			return FPSCR_XX;		}		return 0;	case FPSCR_RN_MINF:		if (d->s && (d->m & 0x7)) {			d->m += 8;			return FPSCR_XX;		}		return 0;	}	return 0;}uint32 ppc_fpu_round_single(ppc_single *s) {	switch (FPSCR_RN(gCPU.fpscr)) {	case FPSCR_RN_NEAR:		if (s->m & 0x7) {			if ((s->m & 0x7) != 4) {				s->m += 4;			} else if (s->m & 8) {				s->m += 4;			}			return FPSCR_XX;		}		return 0;	case FPSCR_RN_ZERO:		if (s->m & 0x7) {			return FPSCR_XX;		}		return 0;	case FPSCR_RN_PINF:		if (!s->s && (s->m & 0x7)) {			s->m += 8;			return FPSCR_XX;		}		return 0;	case FPSCR_RN_MINF:		if (s->s && (s->m & 0x7)) {			s->m += 8;			return FPSCR_XX;		}		return 0;	}	return 0;}uint32 ppc_fpu_round_double(ppc_double *s) {	switch (FPSCR_RN(gCPU.fpscr)) {	case FPSCR_RN_NEAR:		if (s->m & 0x7) {			if ((s->m & 0x7) != 4) {				s->m += 4;			} else if (s->m & 8) {				s->m += 4;			}			return FPSCR_XX;		}		return 0;	case FPSCR_RN_ZERO:		if (s->m & 0x7) {			return FPSCR_XX;		}		return 0;	case FPSCR_RN_PINF:		if (!s->s && (s->m & 0x7)) {			s->m += 8;			return FPSCR_XX;		}		return 0;	case FPSCR_RN_MINF:		if (s->s && (s->m & 0x7)) {			s->m += 8;			return FPSCR_XX;		}		return 0;	}	return 0;}uint32 ppc_fpu_pack_double(ppc_double *d, uint64 *res){	// .124	uint32 ret = 0;//	ht_printf("pd_type: %d\n", d.type);	switch (d->type) {	case ppc_fpr_norm://		ht_printf("pd: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);		d->e += 1023; // bias exponent//		ht_printf("pd: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);		if (d->e > 0) {			ret |= ppc_fpu_round(d);			if (d->m & (1ULL<<56)) {				d->e++;				d->m >>= 4;			} else {				d->m >>= 3;			}			if (d->e >= 2047) {				d->e = 2047;				d->m = 0;				ret |= FPSCR_OX;			}		} else {			// number is denormalized			d->e = -d->e+1;			if (d->e <= 56) {				d->m >>= d->e;				ret |= ppc_fpu_round(d);				d->m <<= 1;				if (d->m & (1ULL<<56)) {					d->e = 1;					d->m = 0;				} else {					d->e = 0;					d->m >>= 4;					ret |= FPSCR_UX;				}			} else {				// underflow to zero				d->e = 0;				d->m = 0;				ret |= FPSCR_UX;			}		}		break;	case ppc_fpr_zero:		d->e = 0;		d->m = 0;		break;	case ppc_fpr_NaN:		d->e = 2047;		d->m = 1;				break;	case ppc_fpr_Inf:		d->e = 2047;		d->m = 0;		break;	}//	ht_printf("pd: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);	FPD_PACK_VAR(*res, d->s, d->e, d->m);	return ret;}uint32 ppc_fpu_pack_single(ppc_double *d, uint32 *res){	// .124	uint32 ret = 0;	switch (d->type) {	case ppc_fpr_norm://		ht_printf("ps: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);		d->e += 127; // bias exponent		d->m >>= 29;//		ht_printf("ps: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);		if (d->e > 0) {			ret |= ppc_fpu_round_double(d);			if (d->m & (1ULL<<27)) {				d->e++;				d->m >>= 4;			} else {				d->m >>= 3;			}			if (d->e >= 255) {				d->e = 255;				d->m = 0;				ret |= FPSCR_OX;			}		} else {			// number is denormalized			d->e = -d->e+1;			if (d->e <= 27) {				d->m >>= d->e;				ret |= ppc_fpu_round_double(d);				d->m <<= 1;				if (d->m & (1ULL<<27)) {					d->e = 1;					d->m = 0;				} else {					d->e = 0;					d->m >>= 4;					ret |= FPSCR_UX;				}			} else {				// underflow to zero				d->e = 0;				d->m = 0;				ret |= FPSCR_UX;			}		}		break;	case ppc_fpr_zero:		d->e = 0;		d->m = 0;		break;	case ppc_fpr_NaN:		d->e = 255;		d->m = 1;		break;	case ppc_fpr_Inf:		d->e = 255;		d->m = 0;		break;	}//	ht_printf("ps: %qx: s:%d e:%d m:%qx\n", d, d.s, d.e, d.m);	FPS_PACK_VAR(*res, d->s, d->e, d->m);	return ret;}void ppc_fpu_single_to_double(ppc_single *s, ppc_double *d) {	d->s = s->s;	d->e = s->e;	d->m = ((uint64)s->m)<<29;	d->type = s->type;}uint32 ppc_fpu_pack_double_as_single(ppc_double *d, uint64 *res){	ppc_single s;	s.m = d->m >> 29;	s.e = d->e;	s.s = d->s;	s.type = d->type;	uint32 ret = 0;		switch (s.type) {	case ppc_fpr_norm: 		s.e = d->e+127;		if (s.e > 0) {			ret |= ppc_fpu_round_single(&s);			if (s.m & (1<<27)) {				s.e++;				s.m >>= 4;			} else {				s.m >>= 3;			}			if (s.e >= 255) {				s.type = ppc_fpr_Inf;				s.e = 255;				s.m = 0;				ret |= FPSCR_OX;			}			d->e = s.e-127;		} else {			// number is denormalized			s.e = -s.e+1;			if (s.e <= 27) {				s.m >>= s.e;				ret |= ppc_fpu_round_single(&s);				s.m <<= 1;				if (s.m & (1<<27)) {					s.e = 1;					s.m = 0;				} else {					s.e = 0;					s.m >>= 4;					ret |= FPSCR_UX;				}			} else {				// underflow to zero				s.type = ppc_fpr_zero;				s.e = 0;				s.m = 0;				ret |= FPSCR_UX;			}		}		break;	case ppc_fpr_zero:		s.e = 0;		s.m = 0;		break;	case ppc_fpr_NaN:		s.e = 2047;		s.m = 1;				break;	case ppc_fpr_Inf:		s.e = 2047;		s.m = 0;		break;	}		if (s.type == ppc_fpr_norm) {		d->m = ((uint64)(s.m))<<32;	} else {		d->m = s.m;	}//	ht_printf("dm: %qx\n", d.m);	ret |= ppc_fpu_pack_double(d, res);	return ret;}uint32 ppc_fpu_double_to_int(ppc_double *d){	switch (d->type) {	case ppc_fpr_norm: {		if (d->e < 0) {			switch (FPSCR_RN(gCPU.fpscr)) {			case FPSCR_RN_NEAR:				if (d->e < -1) {					return 0;				} else {					return d->s ? (uint32)-1 : 1;				}			case FPSCR_RN_ZERO:				return 0;			case FPSCR_RN_PINF:				if (d->s) {					return 0;				} else {					return 1;				}			case FPSCR_RN_MINF:				if (d->s) {					return (uint32)-1;				} else {					return 0;				}			}		}		if (d->e >= 31) {			if (d->s) {				return 0x80000000;			} else {				return 0x7fffffff;			}		}				int i=0;		uint64 mask = (1ULL<<(56 - d->e - 1))-1;		// we have to round		switch (FPSCR_RN(gCPU.fpscr)) {		case FPSCR_RN_NEAR:			if (d->m & mask) {				if (d->m & (1ULL<<(56 - d->e - 2))) {					i = 1;				}			}			break;		case FPSCR_RN_ZERO:			break;		case FPSCR_RN_PINF:			if (!d->s && (d->m & mask)) {				i = 1;			}			break;		case FPSCR_RN_MINF:			if (d->s && (d->m & mask)) {				i = 1;			}			break;		}		d->m >>= 56 - d->e - 1;		d->m += i;		return d->s ? -d->m : d->m;	}	case ppc_fpr_zero:		return 0;	case ppc_fpr_Inf:	case ppc_fpr_NaN:		if (d->s) {			return 0x80000000;		} else {			return 0x7fffffff;		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -