-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathia16-ldivmods.S
executable file
·74 lines (73 loc) · 1.9 KB
/
ia16-ldivmods.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "ia16-preamble.h"
/*
* "When integers are divided, the result of the / operator is
* the algebraic quotient with any fractional part discarded."
*
* (footnote) "This is often called `truncation towards zero.'"
* -- N1570 draft of ISO/IEC 9899:2011 ("C11")
*
* CMU's SEI CERT C Coding Standard document (https://wiki.sei.cmu.edu/
* confluence/pages/viewpage.action?pageId=87152120) further
* elaborates on what this means:
*
* "In C89 (and historical K&R implementations), the meaning of
* the remainder operator for negative operands was
* implementation-defined. This behavior was changed in C99, and
* the change remains in C11. ...
*
* "The result [of the modulo operator, %] has the same sign as
* the dividend (the first operand in the expression)."
*/
.global __ia16_ldivmods
.type __ia16_ldivmods, @function
__ia16_ldivmods:
testw %cx, %cx
js .n_divor
testw %dx, %dx
js .p_divor_n_divnd
/* Both divisor and dividend are positive. */
jmp __ia16_ldivmodu
.p_divor_n_divnd:
/*
* Divisor is positive, dividend is negative. Negate the dividend,
* then negate the results.
*
* (-17L) / 3L == -(17L / 3L) == -5L
* (-17L) % 3L == -(17L % 3L) == -2L
*/
call .negate_dxax
call __ia16_ldivmodu
call .negate_cxbx
jmp .negate_dxax
.n_divor:
call .negate_cxbx
test %dx, %dx
js .n_divor_n_divnd
/*
* Divisor is negative, dividend is positive. Negate the divisor,
* then negate only the quotient.
*
* 17L / (-3L) == -(17L / 3L) == -5L
* 17L % (-3L) == 17L % 3L == 2L
*/
call __ia16_ldivmodu
.negate_dxax:
negw %ax
adcw $0, %dx
negw %dx
ret
.n_divor_n_divnd:
/*
* Both the divisor and dividend are negative. Negate both
* operands, then negate only the remainder.
*
* (-17L) / (-3L) == 17L / 3L == 5L
* (-17L) % (-3L) == -(17L % 3L) == -2L
*/
call .negate_dxax
call __ia16_ldivmodu
.negate_cxbx:
negw %bx
adcw $0, %cx
negw %cx
ret