diff options
Diffstat (limited to 'sys/gnu/arch/i386/fpemul/reg_ld_str.c')
-rw-r--r-- | sys/gnu/arch/i386/fpemul/reg_ld_str.c | 192 |
1 files changed, 117 insertions, 75 deletions
diff --git a/sys/gnu/arch/i386/fpemul/reg_ld_str.c b/sys/gnu/arch/i386/fpemul/reg_ld_str.c index 89b296d7bef..924275393fd 100644 --- a/sys/gnu/arch/i386/fpemul/reg_ld_str.c +++ b/sys/gnu/arch/i386/fpemul/reg_ld_str.c @@ -1,4 +1,4 @@ -/* $OpenBSD: reg_ld_str.c,v 1.1 1996/08/27 10:32:59 downsj Exp $ */ +/* $OpenBSD: reg_ld_str.c,v 1.2 2003/01/09 22:27:12 miod Exp $ */ /* * reg_ld_str.c * @@ -113,9 +113,9 @@ reg_load_extended(void) REENTRANT_CHECK(OFF); /* Use temporary variables here because FPU_loaded data is static and * hence re-entrancy problems can arise */ - sigl = fuword((unsigned long *) s); - sigh = fuword(1 + (unsigned long *) s); - exp = fusword(4 + (unsigned short *) s); + copyin((unsigned long *)s, &sigl, sizeof(unsigned long)); + copyin(1 + (unsigned long *)s, &sigh, sizeof(unsigned long)); + copyin(4 + (unsigned short *)s, &exp, sizeof(unsigned short)); REENTRANT_CHECK(ON); FPU_loaded_data.sigl = sigl; @@ -176,8 +176,8 @@ reg_load_double(void) unsigned m64, l64; REENTRANT_CHECK(OFF); - m64 = fuword(1 + (unsigned long *) dfloat); - l64 = fuword((unsigned long *) dfloat); + copyin(1 + (unsigned long *)dfloat, &m64, sizeof(unsigned)); + copyin((unsigned long *)dfloat, &l64, sizeof(unsigned)); REENTRANT_CHECK(ON); if (m64 & 0x80000000) @@ -243,7 +243,7 @@ reg_load_single(void) int exp; REENTRANT_CHECK(OFF); - m32 = fuword((unsigned long *) single); + copyin((unsigned long *)single, &m32, sizeof(unsigned)); REENTRANT_CHECK(ON); if (m32 & 0x80000000) @@ -302,8 +302,10 @@ reg_load_int64(void) long long s; REENTRANT_CHECK(OFF); - ((unsigned long *) &s)[0] = fuword((unsigned long *) _s); - ((unsigned long *) &s)[1] = fuword(1 + (unsigned long *) _s); + copyin((unsigned long *)_s, &(((unsigned long *)&s)[0]), + sizeof(unsigned long)); + copyin(1 + (unsigned long *)_s, &(((unsigned long *)&s)[1]), + sizeof(unsigned long)); REENTRANT_CHECK(ON); if (s == 0) { @@ -329,12 +331,11 @@ reg_load_int64(void) void reg_load_int32(void) { - long *_s = (long *) FPU_data_address; long s; int e; REENTRANT_CHECK(OFF); - s = (long) fuword((unsigned long *) _s); + copyin((long *)FPU_data_address, &s, sizeof(long)); REENTRANT_CHECK(ON); if (s == 0) { @@ -361,13 +362,14 @@ reg_load_int32(void) void reg_load_int16(void) { - short *_s = (short *) FPU_data_address; + short tmp; int s, e; REENTRANT_CHECK(OFF); - /* Cast as short to get the sign extended. */ - s = (short) fusword((unsigned short *) _s); + copyin((short *)FPU_data_address, &tmp, sizeof(short)); REENTRANT_CHECK(ON); + /* Cast as short to get the sign extended. */ + s = (short)tmp; if (s == 0) { reg_move(&CONST_Z, &FPU_loaded_data); @@ -396,13 +398,13 @@ reg_load_bcd(void) { char *s = (char *) FPU_data_address; int pos; - unsigned char bcd; + unsigned char bcd, tmp; long long l = 0; for (pos = 8; pos >= 0; pos--) { l *= 10; REENTRANT_CHECK(OFF); - bcd = (unsigned char) fubyte((unsigned char *) s + pos); + copyin(s + pos, &bcd, sizeof(u_char)); REENTRANT_CHECK(ON); l += bcd >> 4; l *= 10; @@ -412,10 +414,9 @@ reg_load_bcd(void) /* Finish all access to user memory before putting stuff into the * static FPU_loaded_data */ REENTRANT_CHECK(OFF); - FPU_loaded_data.sign = - ((unsigned char) fubyte((unsigned char *) s + 9)) & 0x80 ? - SIGN_NEG : SIGN_POS; + copyin(s + 9, &tmp, sizeof(u_char)); REENTRANT_CHECK(ON); + FPU_loaded_data.sign = tmp & 0x80 ? SIGN_NEG : SIGN_POS; if (l == 0) { char sign = FPU_loaded_data.sign; @@ -528,11 +529,12 @@ reg_store_extended(void) ls = 1; ms = 0x80000000; } + sign |= (unsigned short)e; REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 10); */ - suword((unsigned long *) d, ls); - suword(1 + (unsigned long *) d, ms); - susword(4 + (short *) d, (unsigned short) e | sign); + copyout(&ls, (unsigned long *)d, sizeof(int)); + copyout(&ms, 1 + (unsigned long *)d, sizeof(int)); + copyout(&sign, 4 + (short *)d, sizeof(short)); REENTRANT_CHECK(ON); return 1; @@ -660,7 +662,9 @@ reg_store_double(void) if (FPU_st0_tag == TW_Infinity) { l[0] = 0; l[1] = 0x7ff00000; - } else + } else { + long tmpl; + if (FPU_st0_tag == TW_NaN) { /* See if we can get a valid NaN from * the FPU_REG */ @@ -686,12 +690,15 @@ reg_store_double(void) /* Put out the QNaN * indefinite */ put_indefinite: + REENTRANT_CHECK(OFF); /* verify_area(VERIFY_W * RITE, (void *) * dfloat, 8); */ - suword((unsigned long *) dfloat, 0); - suword(1 + (unsigned long *) dfloat, 0xfff80000); + tmpl = 0; + copyout(&tmpl, dfloat, sizeof(long)); + tmpl = 0xfff80000; + copyout(&tmpl, 1 + (long *)dfloat, sizeof(long)); REENTRANT_CHECK(ON); return 1; } else @@ -708,16 +715,14 @@ reg_store_double(void) EXCEPTION(EX_Underflow); } #endif + } if (FPU_st0_ptr->sign) l[1] |= 0x80000000; REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, (void *) dfloat, 8);*/ - suword((u_long *) dfloat, l[0]); - suword((u_long *) dfloat + 1, l[1]); -/* - suword(l[0], (unsigned long *) dfloat); - suword(l[1], 1 + (unsigned long *) dfloat);*/ + copyout(&l[0], (u_long *)dfloat, sizeof(int)); + copyout(&l[1], (u_long *)dfloat + 1, sizeof(int)); REENTRANT_CHECK(ON); return 1; @@ -862,7 +867,8 @@ reg_store_single(void) put_indefinite: REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, (void *) single, 4); */ - suword((unsigned long *) single, 0xffc00000); + templ = 0xffc00000; + copyout(&templ, single, sizeof(long)); REENTRANT_CHECK(ON); return 1; } else @@ -890,7 +896,7 @@ reg_store_single(void) REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, (void *) single, 4); */ - suword((unsigned long *) single, templ); + copyout(&templ, (unsigned long *)single, sizeof(int)); REENTRANT_CHECK(ON); return 1; @@ -936,8 +942,8 @@ reg_store_int64(void) REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, (void *) d, 8); */ - suword((unsigned long *) d, ((long *) &tll)[0]); - suword(1 + (unsigned long *) d, ((long *) &tll)[1]); + copyout(&tll, d, sizeof(long)); + copyout(1 + (long *)&tll, 1 + (long *)d, sizeof(long)); REENTRANT_CHECK(ON); return 1; @@ -955,11 +961,14 @@ reg_store_int32(void) /* Empty register (stack underflow) */ EXCEPTION(EX_StackUnder); if (control_word & EX_Invalid) { + long tmpl; + /* The masked response */ /* Put out the QNaN indefinite */ REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 4);*/ - suword((unsigned long *) d, 0x80000000); + tmpl = 0x80000000; + copyout(&tmpl, d, sizeof(long)); REENTRANT_CHECK(ON); return 1; } else @@ -983,7 +992,7 @@ reg_store_int32(void) REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 4); */ - suword((unsigned long *) d, t.sigl); + copyout(&t.sigl, d, sizeof(long)); REENTRANT_CHECK(ON); return 1; @@ -996,7 +1005,8 @@ reg_store_int16(void) { short *d = (short *) FPU_data_address; FPU_REG t; - short ts; + short ts; /* XXX bug! incorrectly used -- miod */ + int16_t tmp; if (FPU_st0_tag == TW_Empty) { /* Empty register (stack underflow) */ @@ -1006,7 +1016,8 @@ reg_store_int16(void) /* Put out the QNaN indefinite */ REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 2);*/ - susword((unsigned short *) d, 0x8000); + tmp = 0x8000; + copyout(&tmp, d, sizeof(int16_t)); REENTRANT_CHECK(ON); return 1; } else @@ -1030,7 +1041,7 @@ reg_store_int16(void) REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 2); */ - susword((short *) d, (short) t.sigl); + copyout(&t.sigl, d, sizeof(int16_t)); REENTRANT_CHECK(ON); return 1; @@ -1070,11 +1081,12 @@ reg_store_bcd(void) if (control_word & EX_Invalid) { put_indefinite: /* Produce "indefinite" */ + b = 0xff; REENTRANT_CHECK(OFF); /* verify_area(VERIFY_WRITE, d, 10);*/ - subyte((unsigned char *) d + 7, 0xff); - subyte((unsigned char *) d + 8, 0xff); - subyte((unsigned char *) d + 9, 0xff); + copyout(&b, (unsigned char *)d + 7, sizeof(char)); + copyout(&b, (unsigned char *)d + 8, sizeof(char)); + copyout(&b, (unsigned char *)d + 9, sizeof(char)); REENTRANT_CHECK(ON); return 1; } else @@ -1085,11 +1097,11 @@ reg_store_bcd(void) b = div_small(&ll, 10); b |= (div_small(&ll, 10)) << 4; REENTRANT_CHECK(OFF); - subyte((unsigned char *) d + i, b); + copyout(&b, (unsigned char *)d + i, sizeof(char)); REENTRANT_CHECK(ON); } REENTRANT_CHECK(OFF); - subyte((unsigned char *) d + 9, sign); + copyout(&sign, (unsigned char *)d + 9, sizeof(char)); REENTRANT_CHECK(ON); return 1; @@ -1169,13 +1181,16 @@ fldenv(void) int i; REENTRANT_CHECK(OFF); - control_word = fusword((unsigned short *) s); - status_word = fusword((unsigned short *) (s + 4)); - tag_word = fusword((unsigned short *) (s + 8)); - ip_offset = fuword((unsigned long *) (s + 0x0c)); - cs_selector = fuword((unsigned long *) (s + 0x10)); - data_operand_offset = fuword((unsigned long *) (s + 0x14)); - operand_selector = fuword((unsigned long *) (s + 0x18)); + copyin((unsigned short *)s, &control_word, sizeof(unsigned short)); + copyin((unsigned short *)(s + 4), &status_word, sizeof(unsigned short)); + copyin((unsigned short *)(s + 8), &tag_word, sizeof(unsigned short)); + copyin((unsigned long *)(s + 0x0c), &ip_offset, sizeof(unsigned long)); + copyin((unsigned long *)(s + 0x10), &cs_selector, + sizeof(unsigned long)); + copyin((unsigned long *)(s + 0x14), &data_operand_offset, + sizeof(unsigned long)); + copyin((unsigned long *)(s + 0x18), &operand_selector, + sizeof(unsigned long)); REENTRANT_CHECK(ON); top = (status_word >> SW_Top_Shift) & 7; @@ -1279,6 +1294,7 @@ char * fstenv(void) { char *d = (char *) FPU_data_address; + int16_t tmp; /* verify_area(VERIFY_WRITE, d, 28);*/ @@ -1288,13 +1304,15 @@ fstenv(void) #endif /****/ REENTRANT_CHECK(OFF); - susword((unsigned short *) d, control_word); - susword((unsigned short *) (d + 4), (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift)); - susword((unsigned short *) (d + 8), tag_word()); - suword((unsigned long *) (d + 0x0c), ip_offset); - suword((unsigned long *) (d + 0x10), cs_selector); - suword((unsigned long *) (d + 0x14), data_operand_offset); - suword((unsigned long *) (d + 0x18), operand_selector); + copyout(&control_word, d, sizeof(int16_t)); + tmp = (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift); + copyout(&tmp, d + 4, sizeof(int16_t)); + tmp = tag_word(); + copyout(&tmp, d + 8, sizeof(int16_t)); + copyout(&ip_offset, d + 0x0c, sizeof(int32_t)); + copyout(&cs_selector, d + 0x10, sizeof(int32_t)); + copyout(&data_operand_offset, d + 0x14, sizeof(int32_t)); + copyout(&operand_selector, d + 0x18, sizeof(int32_t)); REENTRANT_CHECK(ON); return d + 0x1c; @@ -1308,6 +1326,7 @@ fsave(void) FPU_REG tmp, *rp; int i; short e; + int32_t tmpl; d = fstenv(); /* verify_area(VERIFY_WRITE, d, 80);*/ @@ -1320,9 +1339,10 @@ fsave(void) if (rp->tag == TW_Valid) { if (e >= 0x7fff) { /* Overflow to infinity */ + tmpl = 0; REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); + copyout(&tmpl, d + i * 10, sizeof(int32_t)); + copyout(&tmpl, d + i * 10 + 4, sizeof(int32_t)); REENTRANT_CHECK(ON); e = 0x7fff; } else @@ -1333,55 +1353,77 @@ fsave(void) tmp.exp += -EXTENDED_Emin + 63; /* largest exp to be 62 */ round_to_int(&tmp); REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), tmp.sigl); - suword((unsigned long *) (d + i * 10 + 4), tmp.sigh); + copyout(&tmp.sigl, + d + i * 10, + sizeof(int32_t)); + copyout(&tmp.sigh, + d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); } else { /* Underflow to zero */ + tmpl = 0; REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); + copyout(&tmpl, d + i * 10, + sizeof(int32_t)); + copyout(&tmpl, d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); } e = 0; } else { REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); + copyout(&rp->sigl, d + i * 10, + sizeof(int32_t)); + copyout(&rp->sigh, d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); } } else if (rp->tag == TW_Zero) { + tmpl = 0; REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); + copyout(&tmpl, d + i * 10, sizeof(int32_t)); + copyout(&tmpl, d + i * 10 + 4, sizeof(int32_t)); REENTRANT_CHECK(ON); e = 0; } else if (rp->tag == TW_Infinity) { REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0x80000000); + tmpl = 0; + copyout(&tmpl, d + i * 10, + sizeof(int32_t)); + tmpl = 0x80000000; + copyout(&tmpl, d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); e = 0x7fff; } else if (rp->tag == TW_NaN) { REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); + copyout(&rp->sigl, + d + i * 10, + sizeof(int32_t)); + copyout(&rp->sigh, + d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); e = 0x7fff; } else if (rp->tag == TW_Empty) { /* just copy the reg */ REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); + copyout(&rp->sigl, + d + i * 10, + sizeof(int32_t)); + copyout(&rp->sigh, + d + i * 10 + 4, + sizeof(int32_t)); REENTRANT_CHECK(ON); } e |= rp->sign == SIGN_POS ? 0 : 0x8000; REENTRANT_CHECK(OFF); - susword((unsigned short *) (d + i * 10 + 8), e); + copyout(&e, d + i * 10 + 8, sizeof(int16_t)); REENTRANT_CHECK(ON); } |