📄 vaxconvrt.s
字号:
/* @(#)vaxconvrt.s 4.1 (ULTRIX) 7/2/90 */#include "../machine/emul/vaxemul.h"#include "../machine/psl.h"#include "../machine/emul/vaxregdef.h"/************************************************************************ * * * Copyright (c) 1985, 1986 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, 17-Jul-86 * 002- Fixed the problem which caused the cvtpt instruction not to work * at all. The cause of the problem was a bad expansion of a * macro. * * Stephen Reilly, 14-Nov-85 * 001- Fixed a bad case statement that causes the cvtsp instruction * to fail. * * 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 instructions that # convert between packed decimal strings and the various forms of # numeric string. 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 # # 19 october 1983 # # modified by: # # v01-003 ljk0040 Lawrence J. Kenah 24-Jul-84 # Longword context instructions (INCL and DECL) cannot be used # to modify the sign byte the destination string for CVTSP. # # v01-002 ljk0024 Lawrence J. Kenah 20-Feb-84 # Add code that handles access violation. Perform minor cleanup. # # v01-001 ljk0008 lawrence j. kenah 19-oct-1983 # the emulation code for cvtps, cvtpt, cvtsp, and cvttp # was moved into a separate module. # #-- # include files:/* $psldef # define bit fields in psl * cvtps_def # bit fields in cvtps registers * cvtpt_def # bit fields in cvtpt registers * cvtsp_def # bit fields in cvtsp registers * cvttp_def # bit fields in cvttp registers */ # psect declarations: # begin_mark_point .text .text 2 .set table_size,0pc_table_base: .text 3handler_table_base: .textmodule_base: #+ # functional description: # # the conversion from a packed decimal string to a numeric string # (cvtps and cvtpt instructions) consists of much common code and # two small pieces of code that are instruction specific, the # beginning and a portion of the end processing. the actual routine # exit path is the common exit path from the decimal instruction # emulator, vax$decimal_exit. # # the two routines perform instruction-specific operations on the # first byte in the stream. the bulk of the work is done by a common # subroutine. some instruction-specific end processing is done before # final control is passed to vax$decimal_exit. # # the structure is something like the following. # # cvtps cvtpt # ----- ----- # # store sign character store table address # # | unpack registers # | # | | # \ / # \ / # \ / # | | # v v # # handle unequal srclen and dstlen # # move all digits except last digit # # | | # / \ # / \ # / \ # | | # v v # # move last digit to output use table to move last digit # and sign to output string # | # | | # \ / # \ / # \ / # | | # v v # # vax$decimal_exit # set condition codes and registers # to their final values # # input parameters: # # see instruction-specific entry points # # output parameters: # # r0 = 0 # r1 = address of byte containing most significant digit of # the source string # r2 = 0 # r3 = address of lowest addressed byte of destination string # (see instruction-specific header for details) # # condition codes: # # n <- source string lss 0 # z <- source string eql 0 # v <- decimal overflow # c <- 0 #- #+ # the following table makes a correspondence between the sixteen possible # packed decimal "digits" and their ascii representation. it is used to # generate the sign character for leading separate numeric strings and # to generate all character output for the cvtpx common code. #- .text 2cvtpx_table: .ascii "0123456789+-+-++" .text #+ # functional description: # # the source packed decimal string specified by the source length and # source address operands is converted to a leading separate numeric # string. the destination string specified by the destination length and # destination address operands is replaced by the result. # # conversion is effected by replacing the lowest addressed byte of the # destination string with the ascii character '+' or '-', determined by # the sign of the source string. the remaining bytes of the destination # string are replaced by the ascii representations of the values of the # corresponding packed decimal digits of the source string. # # input parameters: # # r0 = srclen.rw length in digits of input decimal string # r1 = srcaddr.ab address of input packed decimal string # r2 = dstlen.rw number of digits in destination character string # r3 = dstaddr.ab address of destination character string # # output parameters: # # r0 = 0 # r1 = address of byte containing most significant digit of # the source string # r2 = 0 # r3 = address of the sign byte of the destination string # # condition codes: # # n <- source string lss 0 # z <- source string eql 0 # v <- decimal overflow # c <- 0 #- # note that the two entry points vax$cvtps and vax$cvtpt must save the # exact same set of registers because the two routines use a common exit # path that includes a popr instruction that restores registers. in fact, by # saving all registers, even if one or two of them are not needed, we can use # the common exit path from this module. .globl vax$cvtpsvax$cvtps: # pushr $^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> # save the lot pushr $0x0fff # establish_handler convert_accvio# Store address of access violation # handler movab convrt_accvio,r10 extzv $1,$4,r0,r6 # r6 is byte offset to sign "digit" # mark_point cvtps_accvio .text 2 .set table_size,table_size + 1 .word Lcvtps_accvio - module_base .text 3 .word cvtps_accvio - module_base .textLcvtps_accvio: bicb3 $0x0f0,(r1)[r6],r6 # r6 now contains sign "digit" # mark_point cvtps_accvio_a .text 2 .set table_size,table_size + 1 .word Lcvtps_accvio_a - module_base .text 3 .word cvtps_accvio - module_base .textLcvtps_accvio_a: movb cvtpx_table[r6],(r3)+ # store sign character in output string bsbw cvtpx_common # execute bulk as common code #+ # the common code routine returns here with the following relevant input. # # r0 number of digits remaining in source and destination strings # r1 address of least significant digit and sign of input string # r3 address of last byte in destination to be loaded # r8 Sign "digit" from input string # r11 saved psw with condition codes to date (n=0,z,v,c=0) # # cvtps_a_dstaddr(sp) saved r3 at input, address of sign character # # r4 is a scratch register # # if the input string was negative zero, the sign of the output string must # be changed from "-" to "+". in addition, a check is required to insure that # the z-bit has its correct setting if this digit is the first nonzero digit # encountered in the input string. #- tstl r0 # check for no remaining input beql 2f # skip storing digit if nothing there # mark_point cvtps_accvio_b .text 2 .set table_size,table_size + 1 .word Lcvtps_accvio_b - module_base .text 3 .word cvtps_accvio - module_base .textLcvtps_accvio_b: extzv $4,$4,(r1),r4 # get least significant digit beql 1f # skip clearing z-bit if zero bicb2 $psl$m_z,r11 # clear saved z-bit # mark_point cvtps_accvio_c .text 2 .set table_size,table_size + 1 .word Lcvtps_accvio_c - module_base .text 3 .word cvtps_accvio - module_base .textLcvtps_accvio_c:1: movb cvtpx_table[r4],(r3) # store final output digit ### i shouldn't have to fetch the sign twice.2: bicb3 $0x0f0,(r1),r6 # sign "digit" to r6 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: bisb2 $psl$m_n,r11 # set n-bit because sign is "-" bbc $psl$v_z,r11,4f # skip if n-bit set but z-bit clear bicb2 $psl$m_n,r11 # turn off n-bit if negative zero bbs $psl$v_v,r11,4f # leave sign alone if overflow occurred # mark_point cvtps_accvio_d .text 2 .set table_size,table_size + 1 .word Lcvtps_accvio_d - module_base .text 3 .word cvtps_accvio - module_base .textLcvtps_accvio_d: movb $0x26,*cvtps_a_dstaddr(sp) # make output sign "+"4: jmp vax$decimal_exit # exit through common code #+ # functional description: # # the source packed decimal string specified by the source length and # source address operands is converted to a trailing numeric string. the # destination string specified by the destination length and destination # address operands is replaced by the result. the condition code n and z # bits are affected by the value of the source packed decimal string. # # conversion is effected by using the highest addressed byte (even if the # source string value is -0) of the source string (i.e., the byte # containing the sign and the least significant digit) as an unsigned # index into a 256 byte table whose zeroth entry address is specified by # the table address operand. the byte read out of the table replaces the # least significant byte of the destination string. the remaining bytes # of the destination string are replaced by the ascii representations of # the values of the corresponding packed decimal digits of the source # string. # # input parameters: # # r0 <15:0> = srclen.rw length in digits of input decimal string # r0 <31:16> = dstlen.rw number of digits in destination character string # r1 = srcaddr.ab address of input packed decimal string # r2 = tbladdr.ab address of 256-byte table used for sign conversion # r3 = dstaddr.ab address of destination character string # # output parameters: # # r0 = 0 # r3 = address of byte containing most significant digit of # the source string # r2 = 0 # r3 = address of most significant digit of the destination string # # condition codes: # # n <- source string lss 0 # z <- source string eql 0 # v <- decimal overflow # c <- 0 #- # notes: # # 1. note that the two entry points vax$cvtps and vax$cvtpt must save the # exact same set of registers because the two routines use a common exit # path that includes a popr instruction that restores registers. in # fact, by saving all registers, even if one or two of them are not # needed, we can use the common exit path from this module. # # 2. this routine and vax$cvttp must have a separate jsb entry point. # (several other routines could use one but it is not required.) code # that uses the emulator through its jsb entry points cannot be # redirected to a different entry point when the instruction is # restarted after an access violation. the only way that a restart can # be distinguished from a first pass is through an internal fpd bit. the # original sizes for the five operands for cvtpt and cvttp require all # the bits in the four general registers. # # the fpd bit is stored in bit<15> of the "srclen" operand. in order to # insure that instructions that enter the emulator through the # vax$_opcdec exception, rather than through its jsb entry points, # correctly generate reserved operands for lengths in the range 32768 to # 65535, the internal fpd bit cannot be tested at the vax$ entry point. # thus, the extra entry point is required. # # note that this implementation has the peculiar effect that a reserved # operand exception will not be generated if r0<15:0> contains a number # in the range 32768 and 32768+31 inclusive. # # 3. the restart entry point is needed because information is saved in # r0<31:24> if the instruction is interrupted by an access violation. # this information must be cleared out before the length checks are made # or a spurious reserved operand exception would result. #- .globl vax$cvtpt_jsbvax$cvtpt_jsb: # bbcc $cvtpt_v_fpd,r0,vax$cvtpt # have we been here before? bbcc $cvtpt_v_fpd,r0,L700
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -