📄 ilsp.s
字号:
addx.w %d4, %d3 # add any carry to m*m product swap %d6 # %d6 is low 32 bits of final product clr.w %d5 clr.w %d2 # lsw of two mixed products used, swap %d5 # now use msws of longwords swap %d2 add.l %d2, %d5 add.l %d3, %d5 # %d5 now ms 32 bits of final product rts########################################################################## XDEF **************************************************************** ## _060LSP__imulu64_(): Emulate 64-bit unsigned mul instruction ## _060LSP__imuls64_(): Emulate 64-bit signed mul instruction. ## ## This is the library version which is accessed as a subroutine ## and therefore does not work exactly like the 680X0 mul{s,u}.l ## 64-bit multiply instruction. ## ## XREF **************************************************************** ## None ## ## INPUT *************************************************************** ## 0x4(sp) = multiplier ## 0x8(sp) = multiplicand ## 0xc(sp) = pointer to location to place 64-bit result ## ## OUTPUT ************************************************************** ## 0xc(sp) = points to location of 64-bit result ## ## ALGORITHM *********************************************************** ## Perform the multiply in pieces using 16x16->32 unsigned ## multiplies and "add" instructions. ## Set the condition codes as appropriate before performing an ## "rts". ## ##########################################################################set MUL64_CC, -4 global _060LSP__imulu64__060LSP__imulu64_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,MUL64_CC(%a6) # save incoming ccodes mov.l 0x8(%a6),%d0 # store multiplier in d0 beq.w mulu64_zero # handle zero separately mov.l 0xc(%a6),%d1 # get multiplicand in d1 beq.w mulu64_zero # handle zero separately########################################################################## 63 32 0 ## ---------------------------- ## | hi(mplier) * hi(mplicand)| ## ---------------------------- ## ----------------------------- ## | hi(mplier) * lo(mplicand) | ## ----------------------------- ## ----------------------------- ## | lo(mplier) * hi(mplicand) | ## ----------------------------- ## | ----------------------------- ## --|-- | lo(mplier) * lo(mplicand) | ## | ----------------------------- ## ======================================================== ## -------------------------------------------------------- ## | hi(result) | lo(result) | ## -------------------------------------------------------- ##########################################################################mulu64_alg:# load temp registers with operands mov.l %d0,%d2 # mr in d2 mov.l %d0,%d3 # mr in d3 mov.l %d1,%d4 # md in d4 swap %d3 # hi(mr) in lo d3 swap %d4 # hi(md) in lo d4# complete necessary multiplies: mulu.w %d1,%d0 # [1] lo(mr) * lo(md) mulu.w %d3,%d1 # [2] hi(mr) * lo(md) mulu.w %d4,%d2 # [3] lo(mr) * hi(md) mulu.w %d4,%d3 # [4] hi(mr) * hi(md)# add lo portions of [2],[3] to hi portion of [1].# add carries produced from these adds to [4].# lo([1]) is the final lo 16 bits of the result. clr.l %d4 # load d4 w/ zero value swap %d0 # hi([1]) <==> lo([1]) add.w %d1,%d0 # hi([1]) + lo([2]) addx.l %d4,%d3 # [4] + carry add.w %d2,%d0 # hi([1]) + lo([3]) addx.l %d4,%d3 # [4] + carry swap %d0 # lo([1]) <==> hi([1])# lo portions of [2],[3] have been added in to final result.# now, clear lo, put hi in lo reg, and add to [4] clr.w %d1 # clear lo([2]) clr.w %d2 # clear hi([3]) swap %d1 # hi([2]) in lo d1 swap %d2 # hi([3]) in lo d2 add.l %d2,%d1 # [4] + hi([2]) add.l %d3,%d1 # [4] + hi([3])# now, grab the condition codes. only one that can be set is 'N'.# 'N' CAN be set if the operation is unsigned if bit 63 is set. mov.w MUL64_CC(%a6),%d4 andi.b &0x10,%d4 # keep old 'X' bit tst.l %d1 # may set 'N' bit bpl.b mulu64_ddone ori.b &0x8,%d4 # set 'N' bitmulu64_ddone: mov.w %d4,%cc# here, the result is in d1 and d0. the current strategy is to save# the values at the location pointed to by a0.# use movm here to not disturb the condition codes.mulu64_end: exg %d1,%d0 movm.l &0x0003,([0x10,%a6]) # save result# EPILOGUE BEGIN ######################################################### fmovm.l (%sp)+,&0x0 # restore no fpregs movm.l (%sp)+,&0x001c # restore d2-d4 unlk %a6# EPILOGUE END ########################################################## rts# one or both of the operands is zero so the result is also zero.# save the zero result to the register file and set the 'Z' ccode bit.mulu64_zero: clr.l %d0 clr.l %d1 mov.w MUL64_CC(%a6),%d4 andi.b &0x10,%d4 ori.b &0x4,%d4 mov.w %d4,%cc # set 'Z' ccode bit bra.b mulu64_end########### muls.l ########### global _060LSP__imuls64__060LSP__imuls64_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3c00,-(%sp) # save d2-d5# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,MUL64_CC(%a6) # save incoming ccodes mov.l 0x8(%a6),%d0 # store multiplier in d0 beq.b mulu64_zero # handle zero separately mov.l 0xc(%a6),%d1 # get multiplicand in d1 beq.b mulu64_zero # handle zero separately clr.b %d5 # clear sign tag tst.l %d0 # is multiplier negative? bge.b muls64_chk_md_sgn # no neg.l %d0 # make multiplier positive ori.b &0x1,%d5 # save multiplier sgn# the result sign is the exclusive or of the operand sign bits.muls64_chk_md_sgn: tst.l %d1 # is multiplicand negative? bge.b muls64_alg # no neg.l %d1 # make multiplicand positive eori.b &0x1,%d5 # calculate correct sign########################################################################## 63 32 0 ## ---------------------------- ## | hi(mplier) * hi(mplicand)| ## ---------------------------- ## ----------------------------- ## | hi(mplier) * lo(mplicand) | ## ----------------------------- ## ----------------------------- ## | lo(mplier) * hi(mplicand) | ## ----------------------------- ## | ----------------------------- ## --|-- | lo(mplier) * lo(mplicand) | ## | ----------------------------- ## ======================================================== ## -------------------------------------------------------- ## | hi(result) | lo(result) | ## -------------------------------------------------------- ##########################################################################muls64_alg:# load temp registers with operands mov.l %d0,%d2 # mr in d2 mov.l %d0,%d3 # mr in d3 mov.l %d1,%d4 # md in d4 swap %d3 # hi(mr) in lo d3 swap %d4 # hi(md) in lo d4# complete necessary multiplies: mulu.w %d1,%d0 # [1] lo(mr) * lo(md) mulu.w %d3,%d1 # [2] hi(mr) * lo(md) mulu.w %d4,%d2 # [3] lo(mr) * hi(md) mulu.w %d4,%d3 # [4] hi(mr) * hi(md)# add lo portions of [2],[3] to hi portion of [1].# add carries produced from these adds to [4].# lo([1]) is the final lo 16 bits of the result. clr.l %d4 # load d4 w/ zero value swap %d0 # hi([1]) <==> lo([1]) add.w %d1,%d0 # hi([1]) + lo([2]) addx.l %d4,%d3 # [4] + carry add.w %d2,%d0 # hi([1]) + lo([3]) addx.l %d4,%d3 # [4] + carry swap %d0 # lo([1]) <==> hi([1])# lo portions of [2],[3] have been added in to final result.# now, clear lo, put hi in lo reg, and add to [4] clr.w %d1 # clear lo([2]) clr.w %d2 # clear hi([3]) swap %d1 # hi([2]) in lo d1 swap %d2 # hi([3]) in lo d2 add.l %d2,%d1 # [4] + hi([2]) add.l %d3,%d1 # [4] + hi([3]) tst.b %d5 # should result be signed? beq.b muls64_done # no# result should be a signed negative number.# compute 2's complement of the unsigned number:# -negate all bits and add 1muls64_neg: not.l %d0 # negate lo(result) bits not.l %d1 # negate hi(result) bits addq.l &1,%d0 # add 1 to lo(result) addx.l %d4,%d1 # add carry to hi(result)muls64_done: mov.w MUL64_CC(%a6),%d4 andi.b &0x10,%d4 # keep old 'X' bit tst.l %d1 # may set 'N' bit bpl.b muls64_ddone ori.b &0x8,%d4 # set 'N' bitmuls64_ddone: mov.w %d4,%cc# here, the result is in d1 and d0. the current strategy is to save# the values at the location pointed to by a0.# use movm here to not disturb the condition codes.muls64_end: exg %d1,%d0 movm.l &0x0003,([0x10,%a6]) # save result at (a0)# EPILOGUE BEGIN ######################################################### fmovm.l (%sp)+,&0x0 # restore no fpregs movm.l (%sp)+,&0x003c # restore d2-d5 unlk %a6# EPILOGUE END ########################################################## rts# one or both of the operands is zero so the result is also zero.# save the zero result to the register file and set the 'Z' ccode bit.muls64_zero: clr.l %d0 clr.l %d1 mov.w MUL64_CC(%a6),%d4 andi.b &0x10,%d4 ori.b &0x4,%d4 mov.w %d4,%cc # set 'Z' ccode bit bra.b muls64_end########################################################################## XDEF **************************************************************** ## _060LSP__cmp2_Ab_(): Emulate "cmp2.b An,<ea>". ## _060LSP__cmp2_Aw_(): Emulate "cmp2.w An,<ea>". ## _060LSP__cmp2_Al_(): Emulate "cmp2.l An,<ea>". ## _060LSP__cmp2_Db_(): Emulate "cmp2.b Dn,<ea>". ## _060LSP__cmp2_Dw_(): Emulate "cmp2.w Dn,<ea>". ## _060LSP__cmp2_Dl_(): Emulate "cmp2.l Dn,<ea>". ## ## This is the library version which is accessed as a subroutine ## and therefore does not work exactly like the 680X0 "cmp2" ## instruction. ## ## XREF **************************************************************** ## None ## ## INPUT *************************************************************** ## 0x4(sp) = Rn ## 0x8(sp) = pointer to boundary pair ## ## OUTPUT ************************************************************** ## cc = condition codes are set correctly ## ## ALGORITHM *********************************************************** ## In the interest of simplicity, all operands are converted to ## longword size whether the operation is byte, word, or long. The ## bounds are sign extended accordingly. If Rn is a data regsiter, Rn is ## also sign extended. If Rn is an address register, it need not be sign ## extended since the full register is always used. ## The condition codes are set correctly before the final "rts". ## ##########################################################################set CMP2_CC, -4 global _060LSP__cmp2_Ab__060LSP__cmp2_Ab_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.b ([0xc,%a6],0x0),%d0 mov.b ([0xc,%a6],0x1),%d1 extb.l %d0 # sign extend lo bnd extb.l %d1 # sign extend hi bnd bra.w l_cmp2_cmp # go do the compare emulation global _060LSP__cmp2_Aw__060LSP__cmp2_Aw_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.w ([0xc,%a6],0x0),%d0 mov.w ([0xc,%a6],0x2),%d1 ext.l %d0 # sign extend lo bnd ext.l %d1 # sign extend hi bnd bra.w l_cmp2_cmp # go do the compare emulation global _060LSP__cmp2_Al__060LSP__cmp2_Al_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.l ([0xc,%a6],0x0),%d0 mov.l ([0xc,%a6],0x4),%d1 bra.w l_cmp2_cmp # go do the compare emulation global _060LSP__cmp2_Db__060LSP__cmp2_Db_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.b ([0xc,%a6],0x0),%d0 mov.b ([0xc,%a6],0x1),%d1 extb.l %d0 # sign extend lo bnd extb.l %d1 # sign extend hi bnd# operation is a data register compare.# sign extend byte to long so we can do simple longword compares. extb.l %d2 # sign extend data byte bra.w l_cmp2_cmp # go do the compare emulation global _060LSP__cmp2_Dw__060LSP__cmp2_Dw_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.w ([0xc,%a6],0x0),%d0 mov.w ([0xc,%a6],0x2),%d1 ext.l %d0 # sign extend lo bnd ext.l %d1 # sign extend hi bnd# operation is a data register compare.# sign extend word to long so we can do simple longword compares. ext.l %d2 # sign extend data word bra.w l_cmp2_cmp # go emulate compare global _060LSP__cmp2_Dl__060LSP__cmp2_Dl_:# PROLOGUE BEGIN ######################################################## link.w %a6,&-4 movm.l &0x3800,-(%sp) # save d2-d4# fmovm.l &0x0,-(%sp) # save no fpregs# PROLOGUE END ########################################################## mov.w %cc,CMP2_CC(%a6) mov.l 0x8(%a6), %d2 # get regval mov.l ([0xc,%a6],0x0),%d0 mov.l ([0xc,%a6],0x4),%d1## To set the ccodes correctly:# (1) save 'Z' bit from (Rn - lo)# (2) save 'Z' and 'N' bits from ((hi - lo) - (Rn - hi))# (3) keep 'X', 'N', and 'V' from before instruction# (4) combine ccodes#l_cmp2_cmp: sub.l %d0, %d2 # (Rn - lo) mov.w %cc, %d3 # fetch resulting ccodes andi.b &0x4, %d3 # keep 'Z' bit sub.l %d0, %d1 # (hi - lo) cmp.l %d1,%d2 # ((hi - lo) - (Rn - hi)) mov.w %cc, %d4 # fetch resulting ccodes or.b %d4, %d3 # combine w/ earlier ccodes andi.b &0x5, %d3 # keep 'Z' and 'N' mov.w CMP2_CC(%a6), %d4 # fetch old ccodes andi.b &0x1a, %d4 # keep 'X','N','V' bits or.b %d3, %d4 # insert new ccodes mov.w %d4,%cc # save new ccodes# EPILOGUE BEGIN ######################################################### fmovm.l (%sp)+,&0x0 # restore no fpregs movm.l (%sp)+,&0x001c # restore d2-d4 unlk %a6# EPILOGUE END ########################################################## rts
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -