Skip to content

Commit fecf6ba

Browse files
committed
asm_tests: Implement x87 invalid operation bit on F64 mode
1 parent 42b1891 commit fecf6ba

19 files changed

Lines changed: 554 additions & 0 deletions
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "0",
5+
"RBX": "1"
6+
},
7+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
8+
}
9+
%endif
10+
11+
; We do one an invalid operation, then a valid one.
12+
; The bit should be set correctly after the invalid operation,
13+
; and cleared by the valid operation.
14+
fldz
15+
fldz
16+
fdiv ; division by zero.
17+
18+
fstsw ax
19+
mov bx, ax
20+
and bx, 1
21+
22+
fld1
23+
fld1
24+
fadd ; valid operation
25+
26+
fstsw ax
27+
and ax, 1
28+
29+
hlt
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
},
6+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
7+
}
8+
%endif
9+
10+
; Test 0/0 = Invalid Operation (should set bit 0 of status word) - reduced precision
11+
fldz
12+
fldz
13+
fdiv
14+
15+
fstsw ax
16+
and rax, 1
17+
18+
hlt
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
}
6+
}
7+
%endif
8+
9+
; Test fcos(+infinity) in reduced precision mode = Invalid Operation (should set bit 0 of status word)
10+
finit
11+
; Set reduced precision mode (64-bit)
12+
fnstcw [rel .cw]
13+
mov ax, [rel .cw]
14+
and ax, 0xFCFF ; Clear precision bits (bits 8-9)
15+
or ax, 0x0200 ; Set to 64-bit precision (10b)
16+
mov [rel .cw], ax
17+
fldcw [rel .cw]
18+
19+
; Load positive infinity: IEEE 754 double precision infinity
20+
mov rax, 0x7FF0000000000000
21+
mov [rel .pos_inf], rax
22+
23+
fld qword [rel .pos_inf]
24+
fcos
25+
26+
fstsw ax
27+
and rax, 1
28+
29+
hlt
30+
31+
.cw:
32+
dw 0
33+
34+
.pos_inf:
35+
dq 0
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1",
5+
"RBX": "1"
6+
},
7+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
8+
}
9+
%endif
10+
11+
section .data
12+
.dummy: dq 0x0
13+
14+
section .text
15+
global _start
16+
17+
_start:
18+
; Test FIST with NaN = Invalid Operation (should set bit 0 of status word) - reduced precision
19+
; Create NaN by 0/0
20+
fldz
21+
fldz
22+
fdiv
23+
24+
fstsw ax
25+
and rax, 1
26+
mov rbx, rax
27+
28+
; Try to convert NaN to integer - this should be invalid
29+
fistp dword [rel .dummy]
30+
31+
fstsw ax
32+
and rax, 1
33+
34+
hlt
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
},
6+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
7+
}
8+
%endif
9+
10+
section .rodata
11+
.thirty: dq 30
12+
13+
section .bss
14+
.dummy: resw 1
15+
16+
section .text
17+
global _start
18+
19+
_start:
20+
21+
; Test FIST with 16-bit overflow = Invalid Operation (should set bit 0 of status word) - reduced precision
22+
; Create a large number that will overflow int16
23+
24+
; Load 2^20 (larger than int16 range: max int16 = 32767, 2^20 = 1048576)
25+
finit
26+
fild dword [rel .thirty]
27+
fld1
28+
fscale
29+
30+
; Try to convert to int16 - this should overflow and be invalid
31+
fistp word [rel .dummy]
32+
33+
fstsw ax
34+
and rax, 1
35+
36+
hlt
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
},
6+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
7+
}
8+
%endif
9+
10+
section .rodata
11+
.fifty: dq 50
12+
13+
section .bss
14+
.dummy: resb 4
15+
16+
section .text
17+
global _start
18+
19+
_start:
20+
21+
; Test FIST with overflow = Invalid Operation (should set bit 0 of status word) - reduced precision
22+
; Create a very large number that will overflow int32
23+
24+
; Load 2^32 (larger than int32 range)
25+
finit
26+
fild dword [rel .fifty]
27+
fld1
28+
fscale
29+
30+
; Try to convert to int32 - this should overflow and be invalid
31+
fistp dword [rel .dummy]
32+
33+
fstsw ax
34+
and rax, 1
35+
36+
hlt
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
},
6+
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
7+
}
8+
%endif
9+
10+
; Test FPREM with simple operands - reduced precision
11+
finit
12+
13+
; Load simple operands: fprem(1.0, 0.0) should set Invalid Operation
14+
fldz
15+
fld1
16+
17+
; Do FPREM: ST(0) = fprem(ST(0), ST(1)) = fprem(1.0, 0.0)
18+
; fprem(1.0, 0.0) should set Invalid Operation because divisor is zero
19+
fprem
20+
21+
fstsw ax
22+
and rax, 1
23+
24+
hlt
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
}
6+
}
7+
%endif
8+
9+
; Test fptan(+infinity) in reduced precision mode = Invalid Operation (should set bit 0 of status word)
10+
finit
11+
; Set reduced precision mode (64-bit)
12+
fnstcw [rel .cw]
13+
mov ax, [rel .cw]
14+
and ax, 0xFCFF ; Clear precision bits (bits 8-9)
15+
or ax, 0x0200 ; Set to 64-bit precision (10b)
16+
mov [rel .cw], ax
17+
fldcw [rel .cw]
18+
19+
; Load positive infinity: IEEE 754 double precision infinity
20+
mov rax, 0x7FF0000000000000
21+
mov [rel .pos_inf], rax
22+
23+
fld qword [rel .pos_inf]
24+
fptan
25+
26+
fstsw ax
27+
and rax, 1
28+
29+
hlt
30+
31+
.cw:
32+
dw 0
33+
34+
.pos_inf:
35+
dq 0
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
}
6+
}
7+
%endif
8+
9+
; Test fsin(+infinity) in reduced precision mode = Invalid Operation (should set bit 0 of status word)
10+
finit
11+
; Set reduced precision mode (64-bit)
12+
fnstcw [rel .cw]
13+
mov ax, [rel .cw]
14+
and ax, 0xFCFF ; Clear precision bits (bits 8-9)
15+
or ax, 0x0200 ; Set to 64-bit precision (10b)
16+
mov [rel .cw], ax
17+
fldcw [rel .cw]
18+
19+
; Load positive infinity: IEEE 754 double precision infinity
20+
mov rax, 0x7FF0000000000000
21+
mov [rel .pos_inf], rax
22+
23+
fld qword [rel .pos_inf]
24+
fsin
25+
26+
fstsw ax
27+
and rax, 1
28+
29+
hlt
30+
31+
.cw:
32+
dw 0
33+
34+
.pos_inf:
35+
dq 0
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
%ifdef CONFIG
2+
{
3+
"RegData": {
4+
"RAX": "1"
5+
}
6+
}
7+
%endif
8+
9+
; Test fsincos(+infinity) in reduced precision mode = Invalid Operation (should set bit 0 of status word)
10+
finit
11+
; Set reduced precision mode (64-bit)
12+
fnstcw [rel .cw]
13+
mov ax, [rel .cw]
14+
and ax, 0xFCFF ; Clear precision bits (bits 8-9)
15+
or ax, 0x0200 ; Set to 64-bit precision (10b)
16+
mov [rel .cw], ax
17+
fldcw [rel .cw]
18+
19+
; Load positive infinity: IEEE 754 double precision infinity
20+
mov rax, 0x7FF0000000000000
21+
mov [rel .pos_inf], rax
22+
23+
fld qword [rel .pos_inf]
24+
fsincos
25+
26+
fstsw ax
27+
and rax, 1
28+
29+
hlt
30+
31+
.cw:
32+
dw 0
33+
34+
.pos_inf:
35+
dq 0

0 commit comments

Comments
 (0)