|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: .file "status.s"
26:
27: .ident "@(#)kern-fp:status.s 1.1"
28: //$tt(*80387 emulator + + + s t a t u s + + + *)
29: // ************************************************************************
30: //
31: // s t a t u s . m o d
32: // ===================
33: //
34: // ================================================================
35: // intel corporation proprietary information
36: // this software is supplied under the terms of a license
37: // agreement or non-disclosure agreement with intel corporation
38: // and may not be copied nor disclosed except in accordance with
39: // the terms of that agreement.
40: // =================================================================
41: //
42: // function:
43: // operation cluster for 80387 status register
44: //
45: // public procedures:
46: // stcw stenv pop_free
47: // incr_top decr_top save_status
48: // restore_status clear_p_error init
49: // clex stsw ldcw
50: // get_precision store_precision get_rnd_control
51: // store_rnd_control u_masked? z_masked?
52: // d_masked? i_masked? o_masked?
53: // get_reg_tag affine_infinity? get_top
54: // set_p_error p_error? set_u_error
55: // set_o_error set_z_error set_i_error
56: // i_error? d_error? set_d_error
57: // set_z_bit clear_z_bit set_s_bit
58: // clear_s_bit set_a_bit clear_a_bits
59: // set_c_bit clear_c_bit store_reg_tag
60: // set_i_masked? set_d_masked? set_z_masked?
61: // clear_cond_bits
62: //
63: // ************************************************************************
64: //
65: //...March 3, 1987...
66: //
67: .data //a_msr segment rw public
68: //
69: //...define the 80387 status register...
70: //
71: //%gs:sr_masks: .byte 0x07f / bit 6 on for d-step 8087 05/21/81
72: //%gs:sr_controls: .byte 0x13
73: //%gs:sr_reserved1: .value 0 / reserveds take care of 386 env
74: //%gs:sr_errors: .byte 0
75: //%gs:sr_flags: .byte 0 / bit 2 off for sim286 09/14/83
76: //%gs:sr_reserved2: .value 0
77: //%gs:sr_tags: .value 0x0ffff
78: //%gs:sr_reserved3: .value 0
79: //%gs:sr_instr_offset: .long 0
80: //%gs:sr_instr_base: .value 0
81: //%gs:sr_reserved4: .value 0
82: //%gs:sr_mem_offset: .long 0
83: //%gs:sr_mem_base: .value 0
84: //%gs:sr_reserved5: .value 0
85: //%gs:sr_regstack: .value 40 dup(0)
86: //#define a_m%gs:sr_data %gs:sr_masks
87: //a_msr ends
88: // assume %ds:a_msr
89: //$nolist
90: #include "fp_e80387.h"
91: //$list
92: //
93: // .globl %gs:sr_mem_offset
94: // .globl %gs:sr_controls
95: // .globl %gs:sr_mem_base
96: // .globl a_m%gs:sr_data
97: // .globl %gs:sr_regstack
98: // .globl %gs:sr_flags
99: // .globl %gs:sr_masks
100: // .globl %gs:sr_errors
101: // .globl %gs:sr_instr_offset
102: // .globl %gs:sr_instr_base
103: .globl incr_top
104: .globl decr_top
105: .globl save_status
106: .globl pop_free
107: .globl ldcw
108: .globl stenv
109: .globl clex
110: .globl stsw
111: .globl stcw
112: .globl get_precision
113: .globl store_precision
114: .globl get_rnd_control
115: .globl store_rnd_control
116: .globl u_masked_
117: .globl d_masked_
118: .globl get_top
119: .globl i_masked_
120: .globl o_masked_
121: .globl get_reg_tag
122: .globl affine_infinity_
123: .globl set_p_error
124: .globl set_u_error
125: .globl set_o_error
126: .globl init
127: .globl clear_p_error
128: .globl set_i_error
129: .globl set_d_error
130: .globl i_error_
131: .globl d_error_
132: .globl p_error_
133: .globl set_z_bit
134: .globl clear_z_bit
135: .globl set_s_bit
136: .globl clear_s_bit
137: .globl set_a_bit
138: .globl clear_cond_bits
139: .globl set_c_bit
140: .globl clear_c_bit
141: .globl store_reg_tag
142: .globl set_i_masked_
143: .globl set_d_masked_
144: .globl set_z_masked_
145: .globl clear_a_bit
146: .globl restore_status
147: .globl set_stk_u_error
148: .globl set_stk_o_error
149: .globl correct_tag_word
150: .globl free_reg
151: //
152: .text //a_med segment er public
153: // --------to be added for unix
154: //.. extrn fpfulong:far,fpfushort:far,fpsulong:far,fpsushort:far
155: //
156: // *************************************************************************
157: //
158: // the routines in this section manipulate the status and control
159: // information stored in the 80387 status data segment, a?msr.
160: //
161: // ************************************************************************
162: // transfer field group: get_precision, store_precision, get_rnd_control
163: // store_rnd_control, get_top, get_reg_tag, store_reg_tag
164: //
165: // inputs: the *get* routines require no input parameters, except for the
166: // procedures get_reg_tag and store_reg_tag which expect the
167: // register number to be in al and cl, respectively
168: // the *store* routines input the value to be stored in al.
169: //
170: // outputs: get_precison returns the 2-bit precision field in dl.
171: // all other routines return justified values in al.
172: // ************************************************************************
173:
174: ALIGN
175: get_precision: //proc
176: movb $precision_mask,%dl // load precision field mask
177: andb %gs:sr_controls,%dl // mask in precision control
178: ret
179: //get_precision endp
180: //
181: ALIGN
182: store_precision: //proc
183: andb $~precision_mask,%gs:sr_controls // clear precision
184: orb %al,%gs:sr_controls // store new precision control
185: ret
186: //store_precision endp
187: //
188: ALIGN
189: get_rnd_control: //proc
190: movb %gs:sr_controls,%al // load control byte
191: andb $rnd_control_mask,%al // mask in rounding control
192: ret
193: //get_rnd_control endp
194: //
195: ALIGN
196: store_rnd_control: //proc
197: andb $~rnd_control_mask,%gs:sr_controls // clear old field
198: orb %al,%gs:sr_controls // store new rounding control
199: ret
200: //store_rnd_control endp
201: //
202: ALIGN
203: get_top: //proc
204: movb %gs:sr_flags,%al // load status flag byte
205: andb $top_mask,%al // mask in top field
206: shrb $3,%al // right justify top field
207: ret
208: //get_top endp
209: //
210: ALIGN
211: get_reg_tag: //proc
212: movzbl %al,%eax // form word bit count
213: mov %eax,%ecx // store in cx
214: shl $1,%ecx // bit count = 2 * reg num
215: mov %ecx,%ebx // else, must examine register
216: shl $2,%ebx // form index to %gs:sr_regstack
217: add %ecx,%ebx // index = 10 * register num
218: add $sr_regstack,%ebx // + start of %gs:sr_regstack
219: movw %gs:sr_tags,%ax // load tag word
220: shrw %cl,%ax // shift to tag of interest
221: andb $empty,%al // mask out other tags
222: cmpb inv,%al // if tag not = 2,
223: jne got_tag // no further decoding needed
224: movw %gs:8(%ebx),%ax // load register exponent
225: andw $0x7fff,%ax // mask off sign bit
226: jnz check_unsupp // if expon /= 0, check unsupported format
227: movb denormd,%al // if exponent zero, denormal
228: ret
229: ALIGN
230: check_unsupp:
231: mov %gs:4(%ebx),%eax // get top 32 bits of significand
232: test $0x080000000,%eax // is highest bit set.
233: jnz check_nan // if so, check for nan
234: movb unsupp,%al // if not, its an unsupported format.
235: ret
236: ALIGN
237: check_nan:
238: and $0x07fffffff,%eax // zero out most significant bit
239: or %gs:(%ebx),%eax // or bottom 32 bits into top 32 bits.
240: movb infinty,%al // tentatively set tag to infinitys
241: jz got_tag // if fraction is 0, its infinity
242: movb inv,%al // fraction is non zero, so tag as nan.
243: got_tag:
244: ret
245: //get_reg_tag endp
246: // ************************************************************************
247: // test status bit group: u_masked?, z_masked?, d_masked?, i_masked?,
248: // o_masked?, affine_infinity?, p_error?, i_error?, d_error?,
249: // set_i_masked?, set_d_masked?
250: //
251: // inputs: no input values are required.
252: //
253: // outputs: all boolean function return the complemented bit value
254: // in the zf. (test with jz on bit = 0.)
255: // ************************************************************************
256: ALIGN
257: u_masked_: //proc
258: testb underflow_mask,%gs:sr_masks // test the u mask
259: ret
260: //u_masked_ endp
261: //
262: ALIGN
263: set_d_masked_: //proc
264: call set_d_error // set the d error
265: d_masked_:
266: testb denorm_mask,%gs:sr_masks // test the d mask
267: ret
268: //set_d_masked_ endp
269: //
270: ALIGN
271: set_i_masked_: //proc
272: call set_i_error // set the i error
273: i_masked_:
274: testb invalid_mask,%gs:sr_masks // test the i mask
275: ret
276: //set_i_masked_ endp
277: //
278: ALIGN
279: o_masked_: //proc
280: testb overflow_mask,%gs:sr_masks // test the o mask
281: ret
282: //o_masked_ endp
283: //
284: ALIGN
285: affine_infinity_: //proc
286: testb infinity_control_mask,%gs:sr_controls // test ic
287: ret
288: //affine_infinity_ endp
289: //
290: ALIGN
291: p_error_: //proc
292: testb $inexact_mask,%gs:sr_errors // test the p error
293: ret
294: //p_error_ endp
295: //
296: ALIGN
297: i_error_: //proc
298: testb invalid_mask,%gs:sr_errors // test the i error
299: ret
300: //i_error_ endp
301: //
302: ALIGN
303: d_error_: //proc
304: testb denorm_mask,%gs:sr_errors // test the d error
305: ret
306: //d_error_ endp
307: // ************************************************************************
308: // set and reset bit group: set_p_error, set_u_error, set_o_error
309: // set_z_masked?, set_i_error, set_d_error, clear_s_bit, clear_z_bit
310: // set_s_bit, set_z_bit, set_a_bit, clear_a_bit, set_c_bit, clear_c_bit
311: // clear_cond_bits, clear_p_error, set_stk_u_error, set_stk_o_error
312: //
313: // inputs: no input values are required.
314: //
315: // outputs: all procedures set or reset the indicated status bit
316: // ************************************************************************
317: ALIGN
318: set_stk_u_error: //proc
319: orb invalid_mask+zero_mask,%gs:sr_errors
320: andb $~a_mask,%gs:sr_flags // clear the a-bit
321: ret
322: //set_stk_u_error endp
323: //
324: ALIGN
325: set_stk_o_error: //proc
326: orb invalid_mask+zero_mask,%gs:sr_errors
327: orb $a_mask,%gs:sr_flags // set the a-bit
328: ret
329: //set_stk_o_error endp
330: //
331: ALIGN
332: set_p_error: //proc
333: orb $inexact_mask,%gs:sr_errors // set the p-error
334: ret
335: //set_p_error endp
336: //
337: ALIGN
338: set_u_error: //proc
339: orb underflow_mask,%gs:sr_errors // set the u-error
340: ret
341: //set_u_error endp
342: //
343: ALIGN
344: set_o_error: //proc
345: orb overflow_mask,%gs:sr_errors // set the o-error
346: ret
347: //set_o_error endp
348: //
349: ALIGN
350: set_i_error: //proc
351: orb invalid_mask,%gs:sr_errors // set the i-error
352: ret
353: //set_i_error endp
354: //
355: ALIGN
356: set_d_error: //proc
357: orb denorm_mask,%gs:sr_errors // set the d-error
358: ret
359: //set_d_error endp
360: //
361: ALIGN
362: set_z_masked_: //proc
363: orb zero_divide_mask,%gs:sr_errors // set the z-error
364: testb zero_divide_mask,%gs:sr_masks // test the z mask
365: ret
366: //set_z_masked_ endp
367: //
368: ALIGN
369: set_s_bit: //proc
370: orb $sign_mask,%gs:sr_flags // set the s-bit
371: ret
372: //set_s_bit endp
373: //
374: ALIGN
375: set_z_bit: //proc
376: orb $zero_mask,%gs:sr_flags // set the z-bit
377: ret
378: //set_z_bit endp
379: //
380: ALIGN
381: set_a_bit: //proc
382: orb $a_mask,%gs:sr_flags // set the a-bit
383: ret
384: //set_a_bit endp
385: //
386: ALIGN
387: set_c_bit: //proc
388: orb $c_mask,%gs:sr_flags // set the c-bit
389: ret
390: //set_c_bit endp
391: //
392: ALIGN
393: clear_s_bit: //proc
394: andb $~sign_mask,%gs:sr_flags // clear the s-bit
395: ret
396: //clear_s_bit endp
397: //
398: ALIGN
399: clear_z_bit: //proc
400: andb $~zero_mask,%gs:sr_flags // clear the z-bit
401: ret
402: //clear_z_bit endp
403: //
404: ALIGN
405: clear_a_bit: //proc
406: andb $~a_mask,%gs:sr_flags // clear the a-bit
407: ret
408: //clear_a_bit endp
409: //
410: ALIGN
411: clear_cond_bits: //proc
412: andb $~(c_mask+zero_mask+sign_mask+a_mask),%gs:sr_flags
413: ret // clear all condition bits
414: //clear_cond_bits endp
415: //
416: ALIGN
417: clear_c_bit: //proc
418: andb $~c_mask,%gs:sr_flags // clear the c-bit
419: ret
420: //clear_c_bit endp
421: //
422: ALIGN
423: clear_p_error: //proc
424: andb $~inexact_mask ,%gs:sr_errors // clear the p-error
425: ret
426: //clear_p_error endp
427: //
428: // ************************************************************************
429: // pop_free:
430: // function:
431: // pops the stack and/or frees the register(s) as required
432: //
433: // ************************************************************************
434: ALIGN
435: pop_free: //proc
436: call i_masked_ // is invalid masked?
437: jnz check_op1 // if so, forget error
438: call i_error_ // check for i-error
439: jnz common_return // if error, dont pop
440:
441: free_reg:
442: check_op1:
443: movb op1_use_up(%ebp),%al // pop or free op1
444: call process_use_up
445: movb op2_use_up(%ebp),%al // pop or free op2
446: process_use_up:
447: cmpb pop_stack,%al // is it a pop_stack?
448: je pop_it // yes, process it
449: xorb free,%al // no, is it free reg?
450: jnz exit_process // no, done with use_up
451: call get_top // yes, get top pointer
452: addb reg_num(%ebp),%al // convert relative num
453: andb $0x07,%al // to absolute reg num
454: empty_reg_tag:
455: movb %al,%cl // cl = reg number
456: movb $empty,%al // al = new tag value
457: store_reg_tag:
458: shlb $1,%cl // bit count = 2 * reg num
459: rorw %cl,%gs:sr_tags // rotate tag to low bits
460: andb $~empty,%gs:sr_tags // clear old reg num tag
461: andb $empty,%al // clear bits 2-7 of new tag
462: orb %al,%gs:sr_tags // store new reg num tag and
463: rolw %cl,%gs:sr_tags // rotate the tag word back
464: exit_process:
465: ret
466: pop_it:
467: call get_top // pop the stack once
468: // the following six instructions have been commented out to prevent
469: // an invalid operation from being signaled when the 87 tos is subject
470: // to a freep st(i) (*6 in the 80387 t-spec). in other words, it will
471: // be o.k. to free st(0) and decrement stackpointer, so it will also be
472: // o.k. to free an already empty st(0).
473: // call get_reg_tag ; get register tag
474: // cmp al,empty ; is the top empty?
475: // jne pop_ok ; no, stack may be popped
476: // call set_i_masked? ; yes, stack error
477: // jz exit_process ; abort if unmasked
478: //pop_ok:
479: // call get_top
480: call empty_reg_tag //set tag of top empty
481: //pop_free endp ; enter incr_top
482: //
483: // **************************************************************************
484: // incr_top:
485: // function:
486: // increments stack pointer
487: //
488: // **************************************************************************
489: FALLSTHRU
490: incr_top: //proc
491: movb $0x08,%cl // load increment top constant
492: jmp adjust_top // merge with decr_top
493: ALIGN
494: //incr_top endp
495: // **************************************************************************
496: // decr_top:
497: // function:
498: // decrements stack pointer
499: //
500: // **************************************************************************
501: ALIGN
502: decr_top: //proc
503: movb $0x38,%cl // load decrement top constant
504: adjust_top:
505: movb %gs:sr_flags,%al // get old top
506: andb $top_mask,%al
507: xorb %al,%gs:sr_flags // clear old top field
508: addb %cl,%al // increment/decrement top
509: andb $top_mask,%al // mask off bits 6-7
510: orb %al,%gs:sr_flags // store new top field
511: common_return:
512: ret
513: //decr_top endp
514: //
515: // ******************************************************************************
516: // restore_status:
517: // function:
518: // implements the 80387 ldenv instruction.
519: // restores status register from memory.
520: //
521: // **********************************************************************
522: ALIGN
523: restore_status: //proc
524: push %ds // save %ds
525: push %gs
526: pop %es // load destination base
527: lds mem_operand_pointer(%ebp),%esi // load environment pointer
528: mov $sr_masks,%edi // load dest offset
529: mov $0x0007,%ecx // load environment from memory
530: cmpb $1,oprnd_siz32(%ebp) //is it a 32 bit operand
531: jne restore_status16 //no restore 16 bit status
532: FAST_MOVSL_ES
533: pop %ds
534: orb $0x40,%gs:sr_masks // set stack mask
535: jmp correct_tag_word
536: ALIGN
537: restore_status16: //16 bit protected mode
538: movsw // mov words
539: inc %edi
540: inc %edi
541: loop restore_status16
542: // ---------
543:
544:
545: //------------------------------------------------------------------------
546: //.. pushad
547: //.. push ds
548: //..restore_status32:
549: //.. push esi
550: //.. call fpfulong
551: //.. pop esi
552: //.. stosd
553: //.. add esi,4
554: //.. loop restore_status32
555: //.. pop ds
556: //.. popad
557: //.. cld
558: //.. ret
559: //..restore_status16:
560: //.. pushad
561: //.. push ds
562: //..restor_loop:
563: //.. push esi
564: //.. call fpfushort
565: //.. pop esi
566: //.. stosw
567: //.. add esi,2
568: //.. add edi,2
569: //.. loop restor_loop
570: //.. pop ds
571: //.. popad
572: //.. cld
573: //---------------------------------------------------------------------
574: pop %ds
575: orb $0x40,%gs:sr_masks // set stack mask
576: correct_tag_word:
577: mov $8,%ecx
578: xor %ebx,%ebx
579: set_tags_loop: //looping through physical locations of 0-7 regs
580: mov $10,%eax
581: mul %ebx
582: mov $sr_regstack,%esi
583: add %eax,%esi
584: mov $0x00000003,%eax
585: and %gs:sr_tags,%eax
586: cmp $3,%eax
587: je loop_back
588: movw %gs:8(%esi),%ax
589: andw $0x7fff,%ax // strip off sign bit
590: jz expon_zero // branch if exponent 0
591: testb $0x80,%gs:7(%esi)
592: jnz max_expon_
593: movb $2,%dl // we have an
594: jmp set_tag // unsupported format
595: ALIGN
596: max_expon_:
597: cmpw $0x7fff,%ax // check for invalid
598: je not_validx // or infinity
599: movb $0,%dl // operand is valid
600: jmp set_tag
601: ALIGN
602: not_validx:
603: movb $2,%dl
604: jmp set_tag
605: ALIGN
606: expon_zero:
607: mov %gs:4(%esi),%eax
608: or %gs:(%esi),%eax
609: movb $1,%dl // set tag to special
610: jz set_tag // if number is +/- 0
611: movb $2,%dl // set tag to denormd
612: set_tag:
613: andb $~empty,%gs:sr_tags // clear old reg num tag
614: orb %dl,%gs:sr_tags // store new reg num tag and
615: loop_back:
616: rorw $2,%gs:sr_tags // get next two bits
617: inc %ebx
618: loop set_tags_loop
619: ret
620: //restore_status endp
621: // **************************************************************************
622: // init:
623: // function:
624: // implements 80387 init instruction. intializes
625: // status register including mode word and error mask.
626: //
627: // ***********************************************************************
628: ALIGN
629: init: //proc
630: movl $0x137f,%eax // initialize mode word
631: movw %ax,%gs:sr_masks
632: movl $0xffffffff,%ax // ax = 0ffffh
633: movw %ax,%gs:sr_tags // register tags = empty
634: xor %eax,%eax // clear a reg
635: movw %ax,%gs:sr_errors // clear the error flags
636: // and %gs:sr_flags,not top_mask ; top of stack = 0, cbit=0
637: ret
638: //init endp
639: // ***********************************************************************
640: // ldcw:
641: // function:
642: // implements 80387 ldcw instruction. 80387 control word
643: // loaded (from memory location specified in instruction).
644: //
645: // ***********************************************************************
646: ALIGN
647: ldcw: //proc
648: les mem_operand_pointer(%ebp),%ebx //get new mode word
649: movw %es:(%ebx),%ax
650: //..
651: //.. pushad
652: //.. push es
653: //.. push ebx
654: //.. call fpfushort
655: //.. pop ebx
656: //.. pop es
657: //.. popad
658: //.. cld
659: //..
660: orw $0x40,%ax // set stack mask
661: movw %ax,%gs:sr_masks // store in status reg
662: ret
663: //ldcw endp
664: // **********************************************************************
665: // stenv:
666: // function:
667: // implements 80387 fstenv instruction. 80387 environmemt
668: // stored (in memory location specified in the instruction).
669: //
670: // **********************************************************************
671: ALIGN
672: stenv: //proc
673: call save_status // store status to memory
674: orb $0x07f,%gs:sr_masks // set all individual masks
675: ret
676: //stenv endp
677: // **********************************************************************
678: // clex:
679: // function:
680: // clears all 80387 errors set in status register
681: //
682: // **********************************************************************
683: ALIGN
684: clex: //proc
685: movb $0,%gs:sr_errors // clear error byte
686: ret
687: //clex endp
688: // **********************************************************************
689: // stsw
690: // function:
691: // stores status word in memory location. (i.e., implements
692: // fstsw instruction.) also implements 'fstsw ax'.
693: //
694: // **********************************************************************
695: ALIGN
696: stsw: //proc
697: movb op2_location(%ebp),%al // load op2 location
698: cmpb $reg,%al // is this fstsw ax?
699: movw %gs:sr_errors,%ax // get status word
700: je stsw_ax // branch on fstsw ax
701: store_word:
702: les mem_operand_pointer(%ebp),%ebx
703: movw %ax,%es:(%ebx) // store status to memory
704:
705: //.. pushad
706: //.. push es
707: //.. push ebx
708: //.. push ax
709: //.. call fpsushort
710: //.. add esp,12
711: //.. popad
712: //.. cld
713: //..
714: ret
715: stsw_ax:
716: movw %ax,saved_eax(%ebp) // store into register ax
717: // above instruction left for completeness but the ax
718: // really has to be restored to the EAX above the global
719: // re-entrant segment
720: // movl %eax, (offset_eax)(%ebp)
721: ret
722: //stsw endp
723: // *********************************************************************
724: // stcw:
725: // function:
726: // stores control word in memory location. (i.e., implements
727: // fstcw instruction.)
728: //
729: // *********************************************************************
730: ALIGN
731: stcw: //proc
732: movw %gs:sr_masks,%ax //get control word
733: andw $0x1f7f,%ax
734: orw $0x1040,%ax //set/reset reserved bits
735: jmp store_word //store it
736: ALIGN
737: //stcw endp
738: // *********************************************************************
739: // save_status:
740: // function:
741: // saves status register to location specified by
742: // memory operand pointer(in es:di)
743: //
744: // *********************************************************************
745: ALIGN
746: save_status: //proc
747: push %ds // save %ds
748: push %gs
749: pop %ds // and set it to address sr_masks
750: andw $0x1f7f,%gs:sr_masks
751: orw $0x1040,%gs:sr_masks //set/reset reserved bits
752: mov $sr_masks,%esi // load source offset
753: les mem_operand_pointer(%ebp),%edi // load destination pointer
754: mov $0x0007,%ecx
755: cmpb $1,oprnd_siz32(%ebp)
756: jne save_status16
757: FAST_MOVSL_ES
758: pop %ds // restore %ds
759: ret
760: ALIGN
761: save_status16: //16 bit protected mode
762: movsw // mov words
763: inc %esi
764: inc %esi
765: loop save_status16
766: //------------------------------------------------------------------------
767: //.. pushad
768: //.. push es
769: //..save_status32:
770: //.. push edi
771: //.. push dword ptr (esi)
772: //.. call fpsulong
773: //.. add esp,8
774: //.. add esi,4
775: //.. add edi,4
776: //.. loop save_status32
777: //.. pop es
778: //.. popad
779: //.. cld
780: //.. ret
781: //..save_status16:
782: //.. pushad
783: //.. push es
784: //..save_loop:
785: //.. push edi
786: //.. push word ptr (esi)
787: //.. call fpsushort
788: //.. add esp,8
789: //.. add edi,2
790: //.. add esi,4
791: //.. loop save_loop
792: //.. pop es
793: //.. popad
794: //.. cld
795: pop %ds // restore %ds
796: ret
797: //save_status endp
798: //
799: //a_med ends
800: //
801: // end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.