Skip to content

Commit

Permalink
unittests/X87: Adds precision and rounding mode tests
Browse files Browse the repository at this point in the history
Tests all the instructions that are affected by FCW PC (or not!)
Only missing tests are fsincos (More easily tested with just fsin and
fcos), and fpatan
  • Loading branch information
Sonicadvance1 committed Dec 5, 2024
1 parent e3d7161 commit 572e0d0
Show file tree
Hide file tree
Showing 32 changed files with 5,674 additions and 0 deletions.
34 changes: 34 additions & 0 deletions unittests/ASM/Includes/x87cw.mac
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
%ifndef X87_CW_INC
%define X87_CW_INC

; Sets x87 precision and rounding modes
; Uses the stack and clobbers rax
; Args: precision constant, rounding constant
%macro set_cw_precision_rounding 2
sub rsp, 2
fnstcw [rsp]
movzx ax, [rsp]

; Precision
and eax, ~(3 << 8)
or eax, %1 << 8

; Rounding
and eax, ~(3 << 10)
or eax, %2 << 10

mov [rsp], ax
fldcw [rsp]
add rsp, 2
%endmacro

x87_prec_32 equ 00b
x87_prec_64 equ 10b
x87_prec_80 equ 11b

x87_round_nearest equ 00b
x87_round_down equ 01b
x87_round_up equ 10b
x87_round_towards_zero equ 11b

%endif
165 changes: 165 additions & 0 deletions unittests/ASM/X87/precision_test_fabs.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x8111111111111111", "0x3fff"],
"XMM1": ["0x8111111111111111", "0x3fff"],
"XMM2": ["0x8111111111111111", "0x3fff"],
"XMM3": ["0x8111111111111111", "0x3fff"],
"XMM4": ["0x8111111111111111", "0x3fff"],
"XMM5": ["0x8111111111111111", "0x3fff"],
"XMM6": ["0x8111111111111111", "0x3fff"],
"XMM7": ["0x8111111111111111", "0x3fff"],
"XMM8": ["0x8111111111111111", "0x3fff"],
"XMM9": ["0x8111111111111111", "0x3fff"],
"XMM10": ["0x8111111111111111", "0x3fff"],
"XMM11": ["0x8111111111111111", "0x3fff"]
}
}
%endif

%include "x87cw.mac"

mov rsp, 0xe000_1000

finit ; enters x87 state

; 80-bit mode, round-nearest
set_cw_precision_rounding x87_prec_80, x87_round_nearest
fld tword [rel .source_1]
fabs
fstp tword [rel .result_1]

; 64-bit mode, round-nearest
set_cw_precision_rounding x87_prec_64, x87_round_nearest
fld tword [rel .source_1]
fabs
fstp tword [rel .result_2]

; 32-bit mode, round-nearest
set_cw_precision_rounding x87_prec_32, x87_round_nearest
fld tword [rel .source_1]
fabs
fstp tword [rel .result_3]

; 80-bit mode, round-down
set_cw_precision_rounding x87_prec_80, x87_round_down
fld tword [rel .source_1]
fabs
fstp tword [rel .result_4]

; 64-bit mode, round-down
set_cw_precision_rounding x87_prec_64, x87_round_down
fld tword [rel .source_1]
fabs
fstp tword [rel .result_5]

; 32-bit mode, round-down
set_cw_precision_rounding x87_prec_32, x87_round_down
fld tword [rel .source_1]
fabs
fstp tword [rel .result_6]

; 80-bit mode, round-up
set_cw_precision_rounding x87_prec_80, x87_round_up
fld tword [rel .source_1]
fabs
fstp tword [rel .result_7]

; 64-bit mode, round-up
set_cw_precision_rounding x87_prec_64, x87_round_up
fld tword [rel .source_1]
fabs
fstp tword [rel .result_8]

; 32-bit mode, round-up
set_cw_precision_rounding x87_prec_32, x87_round_up
fld tword [rel .source_1]
fabs
fstp tword [rel .result_9]

; 80-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_80, x87_round_towards_zero
fld tword [rel .source_1]
fabs
fstp tword [rel .result_10]

; 64-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_64, x87_round_towards_zero
fld tword [rel .source_1]
fabs
fstp tword [rel .result_11]

; 32-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_32, x87_round_towards_zero
fld tword [rel .source_1]
fabs
fstp tword [rel .result_12]

; Fetch results
movups xmm0, [rel .result_1]
movups xmm1, [rel .result_2]
movups xmm2, [rel .result_3]
movups xmm3, [rel .result_4]
movups xmm4, [rel .result_5]
movups xmm5, [rel .result_6]
movups xmm6, [rel .result_7]
movups xmm7, [rel .result_8]
movups xmm8, [rel .result_9]
movups xmm9, [rel .result_10]
movups xmm10, [rel .result_11]
movups xmm11, [rel .result_12]

hlt

; Positive
.source_1:
dq 0x8111_1111_1111_1111
dw 0x3fff

.result_1:
dq 0
dq 0

.result_2:
dq 0
dq 0

.result_3:
dq 0
dq 0

.result_4:
dq 0
dq 0

.result_5:
dq 0
dq 0

.result_6:
dq 0
dq 0

.result_7:
dq 0
dq 0

.result_8:
dq 0
dq 0

.result_9:
dq 0
dq 0

.result_10:
dq 0
dq 0

.result_11:
dq 0
dq 0

.result_12:
dq 0
dq 0
181 changes: 181 additions & 0 deletions unittests/ASM/X87/precision_test_fadd.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
%ifdef CONFIG
{
"RegData": {
"XMM0": ["0x8111111111111111", "0x3fff"],
"XMM1": ["0x8111111111111000", "0x3fff"],
"XMM2": ["0x8111110000000000", "0x3fff"],
"XMM3": ["0x8111111111111111", "0x3fff"],
"XMM4": ["0x8111111111111000", "0x3fff"],
"XMM5": ["0x8111110000000000", "0x3fff"],
"XMM6": ["0x8111111111111111", "0x3fff"],
"XMM7": ["0x8111111111111800", "0x3fff"],
"XMM8": ["0x8111120000000000", "0x3fff"],
"XMM9": ["0x8111111111111111", "0x3fff"],
"XMM10": ["0x8111111111111000", "0x3fff"],
"XMM11": ["0x8111110000000000", "0x3fff"]
}
}
%endif

%include "x87cw.mac"

mov rsp, 0xe000_1000

finit ; enters x87 state

; 80-bit mode, round-nearest
set_cw_precision_rounding x87_prec_80, x87_round_nearest
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_1]

; 64-bit mode, round-nearest
set_cw_precision_rounding x87_prec_64, x87_round_nearest
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_2]

; 32-bit mode, round-nearest
set_cw_precision_rounding x87_prec_32, x87_round_nearest
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_3]

; 80-bit mode, round-down
set_cw_precision_rounding x87_prec_80, x87_round_down
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_4]

; 64-bit mode, round-down
set_cw_precision_rounding x87_prec_64, x87_round_down
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_5]

; 32-bit mode, round-down
set_cw_precision_rounding x87_prec_32, x87_round_down
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_6]

; 80-bit mode, round-up
set_cw_precision_rounding x87_prec_80, x87_round_up
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_7]

; 64-bit mode, round-up
set_cw_precision_rounding x87_prec_64, x87_round_up
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_8]

; 32-bit mode, round-up
set_cw_precision_rounding x87_prec_32, x87_round_up
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_9]

; 80-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_80, x87_round_towards_zero
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_10]

; 64-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_64, x87_round_towards_zero
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_11]

; 32-bit mode, round-towards_zero
set_cw_precision_rounding x87_prec_32, x87_round_towards_zero
fld tword [rel .source_1]
fld tword [rel .source_zero]
faddp
fstp tword [rel .result_12]

; Fetch results
movups xmm0, [rel .result_1]
movups xmm1, [rel .result_2]
movups xmm2, [rel .result_3]
movups xmm3, [rel .result_4]
movups xmm4, [rel .result_5]
movups xmm5, [rel .result_6]
movups xmm6, [rel .result_7]
movups xmm7, [rel .result_8]
movups xmm8, [rel .result_9]
movups xmm9, [rel .result_10]
movups xmm10, [rel .result_11]
movups xmm11, [rel .result_12]

hlt

; Positive
.source_1:
dq 0x8111_1111_1111_1111
dw 0x3fff

.source_zero:
dq 0x0
dq 0x0

.result_1:
dq 0
dq 0

.result_2:
dq 0
dq 0

.result_3:
dq 0
dq 0

.result_4:
dq 0
dq 0

.result_5:
dq 0
dq 0

.result_6:
dq 0
dq 0

.result_7:
dq 0
dq 0

.result_8:
dq 0
dq 0

.result_9:
dq 0
dq 0

.result_10:
dq 0
dq 0

.result_11:
dq 0
dq 0

.result_12:
dq 0
dq 0
Loading

0 comments on commit 572e0d0

Please sign in to comment.