5 # This code tests for the fldcw "load floating point command word"
6 # instruction. On most x86 processors the retired_instruction
7 # performance counter counts this as one instruction. However,
8 # on Pentium 4 systems it counts as two. Therefore this can
9 # affect BBV results on such a system.
10 # fldcw is most often used to set the rouding mode when doing
11 # floating point to integer conversions
13 # It is encoded as "d9 /5" which means
15 # Where xx is the "mod" which will be 00, 01, or 10 indicating offset
16 # and yyy is the register field
20 # these are instructions with similar encodings to fldcw
21 # that can cause false positives if the test isn't explicit enough
31 # check some varied ways of calling fldcw
36 sub $4,%esp # allocate space on stack
39 add $4,%esp # restore stack
53 # register + 8-bit offset
58 fldcw 32(%eax) # eax + 8 bit offset
60 fldcw 32(%ebx) # ebx + 8 bit offset
62 fldcw 32(%ecx) # ecx + 8 bit offset
64 fldcw 32(%edx) # edx + 8 bit offset
66 # register + 32-bit offset
71 fldcw 30000(%eax) # eax + 16 bit offset
73 fldcw 30000(%ebx) # ebx + 16 bit offset
75 fldcw 30000(%ecx) # ecx + 16 bit offset
77 fldcw 30000(%edx) # edx + 16 bit offset
79 # check an fp/integer conversion
80 # in a loop to give a bigger count
85 fldl three # load value onto fp stack
86 fnstcw saved_cw # store control word to mem
87 movzwl saved_cw, %eax # load cw from mem, zero extending
88 movb $12, %ah # set cw for "round to zero"
89 movw %ax, cw # store back to memory
90 fldcw cw # save new rounding mode
91 fistpl result # save stack value as integer to mem
92 fldcw saved_cw # restore old cw
94 loop big_loop # loop to make the count more obvious
96 movl result, %ebx # sanity check to see if the
97 cmp $3,%ebx # result is the expected one
101 mov $4,%eax # write syscall
102 #if defined(VGO_darwin) || defined(VGO_freebsd)
107 #elif defined(VGO_linux)
109 mov $error,%ecx # string
110 mov $22,%edx # length of string
112 #elif defined(VGO_solaris)
122 movl $1, %eax # SYSCALL_EXIT
123 #if defined(VGO_darwin) || defined(VGO_freebsd)
126 #elif defined(VGO_linux)
127 movl result, %ebx # load converted value
129 #elif defined(VGO_solaris)
141 three: .long 0 # a floating point 3.0
143 error: .ascii "Error! Wrong result!\n\0"