📄 vaxdeciml.s
字号:
/* @(#)vaxdeciml.s 4.1 7/2/90 */#include "../machine/emul/vaxemul.h"#include "../machine/psl.h"#include "../machine/emul/vaxregdef.h"/************************************************************************ * * * Copyright (c) 1984,85,86 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, 15-Dec-86 * 002- We were not saving R10 in the cmppx instructions which caused various * instruction faults. * * Stephen Reilly, 15-Jan-86 * 001- Fixed a bad constant with the popr instruction that caused the * cmpp3 and cmpp4 instruction not to work. * * 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 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 # # creation date # # 24 september 1982 # # modified by: # # v01-007 ljk0043 lawrence j. kenah 26-jul-1984 # change strip_zeros routines so that they are more forgiving # when confronted with poorly formed packed decimal strings. # specifically, do not allow string lengths smaller than zero. # # v01-006 ljk0038 lawrence j. kenah 19-jul-1984 # Insure that initial setting of c-bit is preserved when # movp is restarted after an access violation. # # v01-005 ljk0024 lawrence j. Kenah 20-Feb-1984 # Add coe to handle access violations. # # v01-004 ljk0013 lawrence j. kenah 17-nov-1983 # move cvtpl to a separate module. # # v01-003 ljk0008 lawrence j. kenah 18-oct-1983 # move decimal arithmetic and numeric string routines to # separate modules. # # v01-002 ljk0006 lawrence j. kenah 14-oct-1983 # fix code that handles arithmetic traps. add reserved operand # processing. add probes and other code to handle access # violations. # # v01-001 original lawrence j. kenah 24-sep-82 # #-- #+ # 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 # # blbc 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. #- # include files: # $psldef # define bit fields in psl # cmpp3_def # bit fields in cmpp3 registers # cmpp4_def # bit fields in cmpp4 registers # movp_def # bit fields in movp registers # stack_def # stack usage of original exception # begin_mark_point .text .text 2 .set table_size,0pc_table_base: .text 3handler_table_base: .text module_base: # psect declarations: #+ # 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 # ----------------- -------------- .globl decimal$packed_to_binary_tabledecimal$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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -