📄 vaxdeciml.s
字号:
/* @(#)vaxdeciml.s 4.1 7/3/90 *//************************************************************************ * * * Copyright (c) 1983 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. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * 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, 07-Nov-83 * 000- Created this module * ***********************************************************************/ # PLEASE READ # This code should only be used internally and is not intended for # outside use. # # This code is a combination of two modules that were taken from # the VMS group. They are vaxdeciml.mar and vaxeditpc.mar. This # module only contains a subset of the vaxdeciml.mar moodule. The # reason for this was that we only needed to emulate a small fraction # of the packed decimal instructions. # # The instructions that are emulated are ashp, # addp4, cvtlp, movp, editpc. We need to only emulation these # instructions because it is only these instructions that are # used by the either the kernel or utilities. # # Notes: # # Most of the comments are kept from the orignal author. # # There is no error checking for decimal strings that excess # 31 digits. # # The halt instruction is used to indicate a fatal error has # occured. # # # Routines that are global to the rest of the world # .globl vax$addp4 .globl vax$ashp .globl vax$cvtlp .globl vax$movp .globl vax$editpc/* * Mask bits for psw */# define psl$m_c 0x01# define psl$m_v 0x02 # define psl$m_z 0x04 # define psl$m_n 0x08 /* * Bit offsets into psw */# define psl$v_c 0x00# define psl$v_v 0x01 # define psl$v_z 0x02 # define psl$v_n 0x03# define psl$v_dv 0x07/* * Symbols used by the editpc instructions */# define blank 0x20# define minus 0x2d# define zero 0x30/* * Bit positions used by the ash instructions */# define ashp_b_cnt 2# define ashp_v_round 0# define ashp_s_round 8# define ashp_b_round 10# define ashp_w_dstlen 8 .text .align 2 #++ # facility: # # vax-11 instruction emulator # # abstract: # # the routines in this module emulate the vax-11 packed decimal # instructions. these procedures 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 these routines are the registers that # contain the intermediate instruction state. # # environment: # # these routines run at any access mode, at any ipl, and are ast # reentrant. # # author: # # lawrence j. kenah # #-- #+ # there are several techniques that are used throughout the routines in this # module that are worth a comment somewhere. rather than duplicate near # identical commentary in several places, we will describe these general # techniques in a single place. # # 1. the vax-11 architecture specifies that several kinds of input produce # unpredictable results. they are: # # o illegal decimal digit in packed decimal string # # o illegal sign specifier (other than 10 through 15) in low nibble of # highest addressed byte of packed decimal string # # o packed decimal string with even number of digits that contains # other than a zero in the high nibble of the lowest addressed byte # # these routines take full advantage of the meaning of unpredictable. # in general, the code assumes that all input is correct. the operation # of the code for illegal input is not even consistent but is simply # whatever happens to be convenient in a particular place. # # 2. all of these routines accumulate information about condition codes at # several key places in a routine. this information is kept in a # register (usually r11) that is used to set the final condition codes # in the psw. in order to allow the register to obtain its correct # contents when the routine exits (without further affecting the # condition codes), the condition codes are set from the register # (bispsw reg) and the register is then restored with a popr # instruction, which does not affect condition codes. # # 3. there are several instances in these routines where it is necessary to # determine the difference in length between an input and an output # string and perform special processing on the excess digits. when the # longer string is a packed decimal string (it does not matter if the # packed decimal string is an input string or an output string), it is # sometimes useful to convert the difference in digits to a byte count. # # there are four different cases that exist. we will divide these cases # into two sets of two cases, depending on whether the shorter length is # even or odd. # # in the pictures that appear below, a blank box indicates a digit in # the shorter string. a string of three dots in a box indicates a digit # in the longer string. a string of three stars indicates an unused # digit in a decimal string. the box that contains +/- obviously # indicates the sign nibble in a packed decimal string. # # (cont.) # +-------+-------+ # | | | # | *** | ... | # | | | # +-------+-------+ +-------+ - - - + # | | | | # | ... | ... | | ... | ... | # | | | | # + - - - +-------+ + - - - +-------+ # | | | | | | # | ... | | | ... | | # | | | | | | # +-------+ - - - + +-------+ - - - + # | | | | # | | | | | | # | | | | # + - - - + - - - + + - - - + - - - + # | | | | # | | +/- | | | +/- | # | | | | # +-------+-------+ +-------+-------+ # # a longer string odd b longer string even # difference odd difference even # # # case 1 shorter string has even number of digits # # # # +-------+-------+ +-------+-------+ # | | | | | # | ... | ... | | *** | ... | # | | | | | # + - - - + - - - + +-------+ - - - + # | | | | # | ... | ... | | ... | ... | # | | | | # +-------+-------+ +-------+-------+ # | | | | # | | | | | | # | | | | # + - - - + - - - + + - - - + - - - + # | | | | # | | +/- | | | +/- | # | | | | # +-------+-------+ +-------+-------+ # # a longer string odd b longer string even # difference even difference odd # # # case 2 shorter string has odd number of digits # # (cont.) # # in general, the code must calculate the number of bytes that contain # the excess digits. most of the time, the interesting number includes # complete excess bytes. the excess digit in the high nibble of the # highest addressed byte (both parts of case 1) is ignored. # # in three out of four cases, the difference (called r5 from this point # on) can be simply divided by two to obtain a byte count. in one case # (case 2 b), this is not correct. (for example, 3/2 = 1 and we want to # get a result of 2.) note, however, that in both parts of case 2, we # can add 1 to r5 before we divide by two. in case 2 b, this causes the # result to be increased by 1, which is what we want. in case 2 a, # because the original difference is even, an increment of one before we # divide by two has no effect on the final result. # # the correct code sequence to distinguish case 2 b from the other three # cases involves two blbx instructions. a simpler sequence that # accomplishes correct results in all four cases when converting a digit # count to a byte count is something like # # jlbc length-of-shorter,10$ # incl r5 # 10$: ashl $-1,r5,r5 # # where the length of the shorter string will typically be contained in # either r0 or r2. # # note that we could also look at both b parts, performing the extra # incl instruction when the longer string is even. in case 1 b, this # increment transforms an even difference to an odd number but does not # affect the division by two. in case 2 b, the extra increment produces # the correct result. this option is not used in these routines. # # the two routines for cvtsp and cvttp need a slightly different number. # they want the number of bytes including the byte containing the excess # high nibble. for case 2, the above calculation is still valid. for # case 1, it is necessary to add one to r5 after the r5 is divided by # two to obtain the correct byte count. # # 4. there is a routine called strip_zeros that removes high order zeros # from decimal strings. this routine is not used by all of the routines # in this module but only by those routines that perform complicated # calculations on each byte of the input string. for these routines, the # overhead of testing for and discarding leading zeros is less than the # more costly per byte overhead of these routines. #- #+ # the following tables are designed to perform fast conversions between # numbers in the range 0 to 99 and their decimal equivalents. the tables # are used by placing the input parameter into a register and then using # the contents of that register as an index into the table. #- #+ # decimal digits to binary number # # the following table is used to convert a packed decimal byte to its binary # equivalent. # # packed decimal numbers that contain illegal digits in the low nibble # convert as if the low nibble contained a zero. that is, the binary number # will be a multiple of ten. this is done so that this table can be used to # convert the least significant (highest addressed) byte of a decimal string # without first masking off the sign "digit". # # illegal digits in the high nibble produce unpredictable results because the # table does not contain entries to handle these illegal constructs. #- # binary equivalent decimal digits # ----------------- --------------packed_to_binary_table: .byte 00 , 01 , 02 , 03 , 04 # index ^x00 .byte 05 , 06 , 07 , 08 , 09 # to ^x09 .byte 00 , 00 , 00 , 00 , 00 , 00 # illegal decimal digits .byte 10 , 11 , 12 , 13 , 14 # index ^x10 .byte 15 , 16 , 17 , 18 , 19 # to ^x19 .byte 10 , 10 , 10 , 10 , 10 , 10 # illegal decimal digits .byte 20 , 21 , 22 , 23 , 24 # index ^x20 .byte 25 , 26 , 27 , 28 , 29 # to ^x29 .byte 20 , 20 , 20 , 20 , 20 , 20 # illegal decimal digits .byte 30 , 31 , 32 , 33 , 34 # index ^x30 .byte 35 , 36 , 37 , 38 , 39 # to ^x39 .byte 30 , 30 , 30 , 30 , 30 , 30 # illegal decimal digits .byte 40 , 41 , 42 , 43 , 44 # index ^x40 .byte 45 , 46 , 47 , 48 , 49 # to ^x49
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -