fis-gtm/sr_x86_64/op_forloop.s

184 lines
4.7 KiB
ArmAsm
Raw Permalink Normal View History

#################################################################
# #
2024-07-19 11:43:27 -04:00
# Copyright 2007, 2012 Fidelity Information Services, Inc #
# #
# This source code contains the intellectual property #
# of its copyright holder(s), and is made available #
# under a license. If you do not know the terms of #
# the license, please stop and do not read further. #
# #
#################################################################
# PAGE ,132
.title op_forloop.s
# .386
# .MODEL FLAT, C
.include "g_msf.si"
.include "linkage.si"
.INCLUDE "mval_def.si"
.sbttl op_forloop
# PAGE +
# Called with the stack contents:
# call return
# ptr to index mval
# ptr to step mval
# ptr to terminator mval
# loop address
.DATA
.extern frame_pointer
ten_dd:
.long 10
.text
.extern add_mvals
.extern numcmp
.extern s2n
loop = 32
term = 24
step = 16
indx = 8
# PUBLIC op_forloop
ENTRY op_forloop
movq frame_pointer(REG_IP),REG64_SCRATCH1
popq msf_mpc_off(REG64_SCRATCH1)
#Push the arguments on stack Argument registers are used in intermediate logic
pushq REG64_ARG3 #loop address. Return address
pushq REG64_ARG2
pushq REG64_ARG1
pushq REG64_ARG0
enter $0, $0 #rbp pushed on stack and then rbp = rsp
pushq REG_XFER_TABLE
movq indx(REG_FRAME_POINTER),REG64_ARG1
2024-07-19 11:43:27 -04:00
mv_force_defined_strict REG64_ARG1, l0 # disregard NOUNDEF
movq REG64_ARG1, indx(REG_FRAME_POINTER)
mv_force_num REG64_ARG1, l1
movq indx(REG_FRAME_POINTER),REG64_ARG1
movq step(REG_FRAME_POINTER),REG64_ARG0
movw mval_w_mvtype(REG64_ARG1),REG16_ACCUM
movw mval_w_mvtype(REG64_ARG0),REG16_ARG2
andw REG16_ARG2,REG16_ACCUM
testw $mval_m_int_without_nm,REG16_ACCUM
je L66
movl mval_l_m1(REG64_ARG1),REG32_ACCUM
addl mval_l_m1(REG64_ARG0),REG32_ACCUM
cmpl $MANT_HI,REG32_ACCUM
jge L68
cmpl $-MANT_HI,REG32_ACCUM
jle L67
movw $mval_m_int,mval_w_mvtype(REG64_ARG1)
movl REG32_ACCUM,mval_l_m1(REG64_ARG1)
jmp L63
L67: movb $mval_esign_mask,mval_b_exp(REG64_ARG1) #set sign bit
negl REG32_ACCUM
jmp L69
L68: movb $0,mval_b_exp(REG64_ARG1) # clear sign bit
L69: movw $mval_m_nm,mval_w_mvtype(REG64_ARG1)
orb $69,mval_b_exp(REG64_ARG1) # set exponent field
movl REG32_ACCUM,REG32_SCRATCH1
movl $0,REG32_ARG2
idivl ten_dd(REG_IP),REG32_ACCUM
movl REG32_ACCUM,mval_l_m1(REG64_ARG1)
imull $10,REG32_ACCUM,REG32_ACCUM
subl REG32_ACCUM,REG32_SCRATCH1
imull $MANT_LO,REG32_SCRATCH1,REG32_SCRATCH1
movl REG32_SCRATCH1,mval_l_m0(REG64_ARG1)
jmp L63
L66: movq REG64_ARG1,REG64_ARG3
movl $0,REG32_ARG2
movq REG64_ARG0,REG64_ARG1
movq REG64_ARG3,REG64_ARG0
call add_mvals
movq indx(REG_FRAME_POINTER),REG64_ARG1
L63: movq step(REG_FRAME_POINTER),REG64_ARG0
testw $mval_m_int_without_nm,mval_w_mvtype(REG64_ARG0)
jne a
cmpb $0,mval_b_exp(REG64_ARG0)
jl b
jmp a2
a: cmpl $0,mval_l_m1(REG64_ARG0)
jl b
a2: movq term(REG_FRAME_POINTER),REG64_ARG0
jmp e
b: movq REG64_ARG1,REG64_ARG0 # if step is negative, reverse compare
movq term(REG_FRAME_POINTER),REG64_ARG1
e: # compare indx and term
movw mval_w_mvtype(REG64_ARG1),REG16_ACCUM
movw mval_w_mvtype(REG64_ARG0),REG16_ARG2
andw REG16_ARG2,REG16_ACCUM
testw $2,REG16_ACCUM
je ccmp
movl mval_l_m1(REG64_ARG1),REG32_ACCUM
subl mval_l_m1(REG64_ARG0),REG32_ACCUM
jmp tcmp
ccmp: xchgq REG64_ARG0,REG64_ARG1
call numcmp
cmpl $0,REG32_ACCUM
tcmp: jle d
movq indx(REG_FRAME_POINTER),REG64_ARG1
movq step(REG_FRAME_POINTER),REG64_ARG0
movw mval_w_mvtype(REG64_ARG1),REG16_ACCUM
movw mval_w_mvtype(REG64_ARG0),REG16_ARG2
andw REG16_ARG2,REG16_ACCUM
testw $mval_m_int_without_nm,REG16_ACCUM
je l66
movl mval_l_m1(REG64_ARG1),REG32_ACCUM
subl mval_l_m1(REG64_ARG0),REG32_ACCUM
cmpl $MANT_HI,REG32_ACCUM
jge l68
cmpl $-MANT_HI,REG32_ACCUM
jle l67
movw $mval_m_int,mval_w_mvtype(REG64_ARG1)
movl REG32_ACCUM,mval_l_m1(REG64_ARG1)
jmp l63
l67: movb $mval_esign_mask,mval_b_exp(REG64_ARG1) # set sign bit
negl REG32_ACCUM
jmp l69
l68: movb $0,mval_b_exp(REG64_ARG1) # clear sign bit
l69: movw $mval_m_nm,mval_w_mvtype(REG64_ARG1)
orb $69,mval_b_exp(REG64_ARG1)
movl REG32_ACCUM,REG32_SCRATCH1
movl $0,REG32_ARG2 #set edx to 0 before div
idivl ten_dd(REG_IP),REG32_ACCUM
movl REG32_ACCUM,mval_l_m1(REG64_ARG1)
imull $10,REG32_ACCUM,REG32_ACCUM
subl REG32_ACCUM,REG32_SCRATCH1
imull $MANT_LO,REG32_SCRATCH1,REG32_SCRATCH1
movl REG32_SCRATCH1,mval_l_m0(REG64_ARG1)
jmp l63
l66: movq REG64_ARG1,REG64_ARG3
movl $1,REG32_ARG2
movq REG64_ARG0,REG64_ARG1
movq REG64_ARG3,REG64_ARG0 #First and fourth args are same
call add_mvals
l63: popq REG_XFER_TABLE
leave
addq $32,REG_SP #Pop all incoming arguments
movq frame_pointer(REG_IP),REG64_SCRATCH1
pushq msf_mpc_off(REG64_SCRATCH1)
ret
d: popq REG_XFER_TABLE
leave
addq $24,REG_SP #Pop all the arguments except loop address
ret
# op_forloop ENDP
# END