;
; Исходный код среды исполнения ПВТ-ОО.
;
; Этот исходный код является частью проекта ПВТ-ОО.
;
; Copyright © 2021 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять её и/или
; изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она может быть полезна,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <http://www.gnu.org/licenses/>.
;
; <fold avt.lang.Real (natives)>
method avt.lang.Real$nextAfter$real$, \
value, real ; returns real <fold >
loc addend, real
menter
lverify value, TAG_REAL
mov r0, [.value+$00]
movsx r6, word[.value+$08]
cmp r0, [avt.lang.Real$NEGATIVE_INFINITY+$00]
jne @F
cmp r6w, [avt.lang.Real$NEGATIVE_INFINITY+$08]
jne @F
fld tbyte[avt.lang.Real$NEGATIVE_MAX_VALUE]
jmp .L.RET
@@: cmp r0, [avt.lang.Real$NEGATIVE_MIN_VALUE+$00]
jne @F
cmp r6w, [avt.lang.Real$NEGATIVE_MIN_VALUE+$08]
jne @F
fld tbyte[avt.lang.Real$NEGATIVE_ZERO_BITS]
jmp .L.RET
@@: cmp r0, [avt.lang.Real$NEGATIVE_ZERO_BITS+$00]
jne @F
cmp r6w, [avt.lang.Real$NEGATIVE_ZERO_BITS+$08]
jne @F
fldz
jmp .L.RET
@@: mov r1, r6
and r1, $7fff
test r1, r1
jnz @F
mov r2d, $00000001
xor r7d, r7d
jmp .L.NXT
@@: cmp r1, $3f
jg @F
dec r1
mov r2d, $00000001
shl r2, r1b
xor r7d, r7d
jmp .L.NXT
@@: mov r2, [avt.lang.Real$EMPTY_SIGNIFICAND]
lea r7, [r1-$3f]
.L.NXT: mov qword[.addend+$00], r2
mov qword[.addend+$08], r7
test r6, $8000
jz @F
cmp r0, [avt.lang.Real$EMPTY_SIGNIFICAND]
jne @F
fld tbyte[.value]
fld tbyte[.addend]
fld tbyte[avt.lang.Real$HALF]
fmulp st1, st0
faddp st1, st0
jmp .L.RET
@@: fld tbyte[.value]
fld tbyte[.addend]
faddp st1, st0
.L.RET: call inst$xpush
mleavet
eleave
; </fold>
method avt.lang.Real$nextBefore$real$, \
value, real ; returns real <fold >
loc addend, real
menter
lverify value, TAG_REAL
mov r0, [.value+$00]
movsx r6, word[.value+$08]
cmp r0, [avt.lang.Real$POSITIVE_INFINITY+$00]
jne @F
cmp r6w, [avt.lang.Real$POSITIVE_INFINITY+$08]
jne @F
fld tbyte[avt.lang.Real$MAX_VALUE]
jmp .L.RET
@@: test r0, r0
jnz @F
test r6w, r6w
jnz @F
fld tbyte[avt.lang.Real$NEGATIVE_ZERO_BITS]
jmp .L.RET
@@: mov r1, r6
and r1, $7fff
test r1, r1
jnz @F
mov r2d, $00000001
xor r7d, r7d
jmp .L.NXT
@@: cmp r1, $3f
jg @F
dec r1
mov r2d, $00000001
shl r2, r1b
xor r7d, r7d
jmp .L.NXT
@@: mov r2, [avt.lang.Real$EMPTY_SIGNIFICAND]
mov r7, r1
sub r7, $3f
.L.NXT: mov qword[.addend+$00], r2
mov qword[.addend+$08], r7
test r6, $8000
jnz @F
cmp r0, [avt.lang.Real$EMPTY_SIGNIFICAND]
jne @F
fld tbyte[.value]
fld tbyte[.addend]
fld tbyte[avt.lang.Real$HALF]
fmulp st1, st0
fsubp st1, st0
jmp .L.RET
@@: fld tbyte[.value]
fld tbyte[.addend]
fsubp st1, st0
.L.RET: call inst$xpush
mleavet
eleave
; </fold>
method avt.lang.Real$toLong2Bits$real$, \
value, real ; returns long2 <fold >
menter
lverify value, TAG_REAL
movsx r0, word[.value+$08]
vmovq xmm0, [.value+$00]
vmovq xmm1, r0
vpslldq xmm1, xmm1, $08
vpor xmm0, xmm0, xmm1
call inst$l2push
mleavex
eleave
; </fold>
; </fold>