📄 vaxashp.s
字号:
/* @(#)vaxashp.s 4.1 Ultrix 7/2/90 */#include "../machine/emul/vaxemul.h"#include "../machine/psl.h"#include "../machine/emul/vaxregdef.h"/************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Modification History * * Stephen Reilly, 27-Apr-84 * 001- An instruction was taken out that should have * * Stephen Reilly, 20-Mar-84 * 000- This code is the modification of the VMS emulation codethat * was written by Larry Kenah. It has been modified to run * on Ultrix. * ***********************************************************************/ #++ # facility: # # vax-11 instruction emulator # # abstract: # # the routine in this module emulates the vax-11 packed decimal # ashp instruction. this procedure can be a part of an emulator # package or can be called directly after the input parameters # have been loaded into the architectural registers. # # the input parameters to this routine are the registers that # contain the intermediate instruction state. # # environment: # # this routine runs at any access mode, at any ipl, and is ast # reentrant. # # author: # # lawrence j. kenah # # creation date # # 18 october 1983 # # modified by: # # V01-002 LJK0024 Lawrence J. Kenah 20-Feb-1984 # Add code to handle access violations. Perform minor cleanup. # # v01-001 ljk0008 lawrence j. kenah 18-oct-1983 # the emulation code for ashp was moved into a separate module. #-- # include files:/* $psldef # define bit fields in psl * $srmdef # define arithmetic trap codes * ashp_def # bit fields in ashp registers * stack_def # stack usage for original exception */ # macro definitions # psect declarations: # BEGIN_MARK_POINT .text .text 2 .set table_size,0pc_table_base: .text 3handler_table_base: .textmodule_base: #+ # functional description: # # the source string specified by the source length and source address # operands is scaled by a power of 10 specified by the count operand. the # destination string specified by the destination length and destination # address operands is replaced by the result. # # a positive count operand effectively multiplies# a negative count # effectively divides# and a zero count just moves and affects condition # codes. when a negative count is specified, the result is rounded using # the round operand. # # input parameters: # # r0<15:0> = srclen.rw number of digits in source character string # r0<23:16> = cnt.rb shift count # r1 = srcaddr.ab address of input character string # r2<15:0> = dstlen.rw length in digits of output decimal string # r2<23:16> = round.rb round operand used with negative shift count # r3 = dstaddr.ab address of destination packed decimal string # # output parameters: # # r0 = 0 # r1 = address of byte containing most significant digit of # the source string # r2 = 0 # r3 = address of byte containing most significant digit of # the destination string # # condition codes: # # n <- destination string lss 0 # z <- destination string eql 0 # v <- decimal overflow # c <- 0 # # algorithm: # # the routine tries as much as possible to work with entire bytes. this # makes the case of an odd shift count more difficult that of an even # shift count. the first part of the routine reduces the case of an odd # shift count to an equivalent operation with an even shift count. # # the instruction proceeds in several stages. in the first stage, after # the input parameters have been verified and stored, the operation is # broken up into four cases, based on the sign and parity (odd or even) # of the shift count. these four cases are treated as follows, in order # of increasing complexity. # # case 1. shift count is negative and even # # the actual shift operation can work with the source string in # place. there is no need to move the source string to an # intermediate work area. # # case 2. shift count is positive and even # # the source string is moved to an intermediate work area and the # sign "digit" is cleared before the actual shift operation takes # place. if the source is worked on in place, then a spurious sign # digit would be moved to the middle of the output string instead # of a zero. The alternative is to keep track of where, in the # several special cases of shifting, the sign digit is looked at. # We chose to use the work area to simplify the later stages of # this routine. # # cases 3 and 4. shift count is odd # # the case of an odd shift count is considerably more difficult # than an even shift count, which is only slightly more complicated # than movp. in the case of an even shift count, various digits # remain in the same place (high nibble or low nibble) in a byte. # for odd shift counts, high nibbles become low nibbles and vice # versa. in addition, digits that were adjacent when viewing the # decimal string as a string of bits proceeding from low address to # high are now separated by a full byte. # # we proceed in two steps. the source string is first moved to a # work area. the string is then shifted by one. this shift reduces # the operation to one of the two even shift counts already # mentioned, where the source to the shift operation is the # modified source string residing in the work area. the details of # the shift-by-one are described below near the code that performs # the actual shift. #-# define ashp_shift_mask 0xf0f0f0f0 # mask used to shift string by one .globl vax$ashpvax$ashp: # pushr $^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> # save the lot pushr $0x0fff movpsl r11 # get initial psl insv $psl$m_z,$0,$4,r11 # set z-bit, clear the rest # ESTABLISH_HANDLER - ; Store address of access # ASHP_ACCVIO ; violation handler movab ashp_accvio,r10 # roprand_check r2 # insure that r2 lequ 31 cmpw r2,$31 blequ 1f brw decimal_roprand1: movzwl r2,r2 # roprand_check r0 # insure that r0 lequ 31 cmpw r0,$31 blequ 1f brw decimal_roprand1: movzwl r0,r0 jsb decimal$strip_zeros_r0_r1 # eliminate any high order zeros movl sp,r8 # remember current top of stack subl2 $20,sp # allocate work area on stack # MARK_POINT ASHP_BSBW_20_a .text 2 .set table_size,table_size + 1 .word Lashp_bsbw_20_a - module_base .text 3 .word ashp_bsbw_20 - module_base .textLashp_bsbw_20_a: jsb decimal$strip_zeros_r0_r1 # Eliminate any high order zeros extzv $1,$4,r2,r2 # convert output digit count to bytes incl r2 # make room for sign as well extzv $1,$4,r0,r0 # same for input string addl3 r0,r1,r6 # get address of sign digit incl r0 # include byte containing sign # MARK_POINT ASHP_20_a .text 2 .set table_size,table_size + 1 .word Lashp_20_a - module_base .text 3 .word ashp_20 - module_base .textLashp_20_a: bicb3 $0x0f0,(r6),r6 # extract sign digit # Form sign of output string in r9 in preferred from (12 for "+" and 13 for # "-") movzbl $12,r9 # assume that input sign is plus caseb r6,$10,$15-10 # dispatch on sign L1: .word 4f-L1 # 10 => + .word 3f-L1 # 11 => - .word 4f-L1 # 12 => + .word 3f-L1 # 13 => - .word 4f-L1 # 14 => + .word 4f-L1 # 15 => +3: incl r9 # change preferred plus to minus bisb2 $psl$m_n,r11 # set n-bit in saved psw # we now retrieve the shift count from the saved r0 and perform the next set # of steps based on the parity and sign of the shift count. note that the # round operand is ignored unless the shift count is strictly less than zero.4: cvtbl ashp_b_cnt(r8),r4 # extract sign-extended shift count blss 5f # branch if shift count negative clrl r5 # ignore "round" for positive shift bsbw ashp_copy_source # move source string to work area blbs r4,6f # do shift by one for odd shift count bicb2 $0x0f,-(r8) # drop sign in saved source string brb ashp_shift_positive # go do the actual shift # the "round" operand is important for negative shifts. if the shift count # is even, the source can be shifted directly into the destination. for odd # shift counts, the source must be moved into the work area on the stack and # shifted by one before the rest of the shift operation takes place.5: extzv $ashp_v_round,$ashp_s_round,ashp_b_round(r8),r5 # store "round" in a safe place blbc r4,ashp_shift_negative # get right to it for even shift count bsbw ashp_copy_source # move source string to work area # for odd shift counts, the saved source string is shifted by one in place. # this is equivalent to a shift of -1 so the shift count (r4) is adjusted # accordingly. the least significant digit is moved to the place occupied by # the sign, the tens digit becomes the units digit, and so on. because the # work area was padded with zeros, this shift moves a zero into the high # order digit of a source string of even length. 6: pushl r0 # we need a scratch register to count decl r0 # want to map {1..16} onto {0..3} ashl $-2,r0,r0 # convert a byte count to longwords # the following loop executes from one to four times such that the entire # source, taken as a collection of longwords, is shifted by one. note that # the two pieces of the source are shifted (rotated) in opposite directions. # note also that the shift mask is applied to one string before the shift and # to the other string after the shift. (this points up the arbitrary choice # of shift mask. we just as well could have chosen the one's complement of # the shift mask and reversed the order of the shift and mask operations for # the two pieces of the source string.)7: rotl $-4,-(r8),r6 # shift left one digit bicl2 $ashp_shift_mask,r6 # clear out old low order digits bicl3 $ashp_shift_mask,-1(r8),r7 # clear out high order digits rotl $4,r7,r7 # shift these digits right one digit bisl3 r6,r7,(r8) # combine the two sets of digits sobgeq r0,7b # keep going if more
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -