Cloutier (https://www.felixcloutier.com/x86/roundpd#fig-4-24) about the third operand of roundsd (the "B" stands for binary, so it's 0...3):
QuoteRound to 00B closest to the infinitely precise result. If two values are equally close, the result is nearest (even) the even value (i.e., the integer value with the least-significant bit of zero).
Round down 01B closest to but no greater than the infinitely precise result. (toward −∞)
Round up 10B closest to but no less than the infinitely precise result. (toward +∞)
Round toward 11B closest to but no greater in absolute value than the infinitely precise result. zero (Truncate)
**** Imm8=0
Start: -123.490000 -123.000000 ; .49->0, up
Start: -123.500000 -124.000000 ; .50->−∞, down
Start: 123.490000 123.000000 ; .49->0, down
Start: 123.500000 124.000000 ; .50->+∞, up
**** Imm8=1
Start: -123.490000 -124.000000 ; down
Start: -123.500000 -124.000000 ; down
Start: 123.490000 123.000000 ; down
Start: 123.500000 123.000000 ; down
**** Imm8=2
Start: -123.490000 -123.000000 ; up
Start: -123.500000 -123.000000 ; up
Start: 123.490000 124.000000 ; up
Start: 123.500000 124.000000 ; up
**** Imm8=3
Start: -123.490000 -123.000000 ; up truncate
Start: -123.500000 -123.000000 ; up truncate
Start: 123.490000 123.000000 ; down truncate
Start: 123.500000 123.000000 ; down truncate
**** Imm8=4
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
**** Imm8=5
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
**** Imm8=6
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
**** Imm8=7
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
**** Imm8=8
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
**** Imm8=9
Start: -123.490000 -124.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
**** Imm8=10
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 124.000000
Start: 123.500000 124.000000
**** Imm8=11
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
Codes 0, 4, 8 are identical.
Codes 1, 9 are identical.
Codes 2, 10 are identical.
Codes 3, 11 are identical.
That implies that bit 3=8 has a different function: "Bit 3 of the immediate byte controls processor behavior for a precision exception... if imm[3] = '1, then the Precision Mask in the MXSCSR is ignored and precision exception is not signaled"
Re bit 2, Cloutier (https://www.felixcloutier.com/x86/roundpd#fig-4-24):
QuoteIF (imm[2] = '1)
THEN // rounding mode is determined by MXCSR.RC
DEST[63:0] := ConvertDPFPToInteger_M(SRC[63:0]);
DEST[127:64] := ConvertDPFPToInteger_M(SRC[127:64]);
ELSE // rounding mode is determined by IMM8.RC
This is why you see four times the same results for 4...7 above: bits 0+1 get ignored.
Googling mxcsr rounding bits "roundsd" puts this post at #4, 4 days after posting :rolleyes:
New testbed:
rct=0
stmxcsr OldControlReg ; save current setting
ldmxcsr NewControlReg ; change to new setting
usemxcsr=0
REPEAT 2
if usemxcsr
Print CrLf$, CrLf$, "mxcsr bin=", Mid$(Bin$(NewControlReg), 17, 3), " (bits 15, 14, 13)"
endif
repeat 4 ; 12
ife (rct and 3)
Print
endif
Print CrLf$, "Imm8 bin=", Right$(Bin$(rct or 8 or usemxcsr), 4)
mov edi, offset numbers
.Repeat
movlps xmm0, REAL8 ptr [edi]
Print Str$("\nStart: %9f\t", f:xmm0)
roundsd xmm1, xmm0, rct or 8 or usemxcsr ; bit 3 set: no exceptions
Print Str$("%9f", f:xmm1)
add edi, REAL8
.Until edi>=offset numbers+8*4
rct=rct+1
endm
usemxcsr=4 ; use the mxcsr register in round 2
endm
ldmxcsr OldControlReg ; restore previous setting
Results:
Imm8 bin=1000
Start: -123.490000 -123.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 124.000000
Imm8 bin=1001
Start: -123.490000 -124.000000
Start: -123.500000 -124.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
Imm8 bin=1010
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 124.000000
Start: 123.500000 124.000000
Imm8 bin=1011
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
mxcsr bin=011 (bits 15, 14, 13)
Imm8 bin=1100
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
Imm8 bin=1101
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
Imm8 bin=1110
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
Imm8 bin=1111
Start: -123.490000 -123.000000
Start: -123.500000 -123.000000
Start: 123.490000 123.000000
Start: 123.500000 123.000000
So it's roundsd xmm1, xmm0, 8 or roundingbits or usemxcsr. The "8" stands for don't throw exceptions, the roundingbits are 0..3, and usemxcsr=4 means ignore the roundingbits.
Full source & exe attached.
@Z: MS Edge.