184 lines
4.7 KiB
ArmAsm
184 lines
4.7 KiB
ArmAsm
|
#################################################################
|
||
|
# #
|
||
|
# Copyright 2007, 2008 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
|
||
|
mv_force_defined REG64_ARG1, l0
|
||
|
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
|
||
|
|