News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

RoundSD

Started by jj2007, July 20, 2023, 04:10:07 AM

Previous topic - Next topic

jj2007

Cloutier 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:
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.

jj2007

Googling mxcsr rounding bits "roundsd" puts this post at #4, 4 days after posting :rolleyes:

jj2007

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.