📄 vaxcvtpl.s
字号:
/* @(#)vaxcvtpl.s 4.1 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, 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 # cvtpl 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-009 ljk0034 Lawrence j. Kenah 08-Jul--1984 # Fix several bugs in restart logic. # # Use r4 instead of r7 as dispatch register for restart routine. # there is a single code path where r7 contains useful data. # Insure that the contents of r7 are preserved across the # occurrence of the cvtpl_5 access violation. # Use special restart path for cvtpl_6. # fix recalculation of srcaddr. # Use saved r2 when saving condition codes. # # v01-008 ljk0033 lawrence j. kenah 06-jul-1984 # Add r10 to register mask used along error path when the # digit count is larger than 31. # # v01-007 ljk0032 Lawrence j. kenah 05-jul-1984 # Fix restart routine to take into account the fact that # restart codes are based at one when computing restart PC. # # v01-006 ljk0030 lawrence j. kenah 20-jun-1984 # Load access violation handler address into r10 before # any useful work (like memory accesses) gets done. # # v01-005 ljk0029 lawrence j. kenah 24-may-1984 # Fix stack offset calculation in exit code when v-bit is # set to reflect in fact the seven registers (not six) have # been saved on the stack. # # v01-004 ljk0024 lawrence j. kenah 22-Feb-1984 # Add code to handle access violation. Perform minor cleanup. # # v01-003 ljk0023 lawrence j. kenah 10-Feb-1984 # Make a write to PC generate a reserved addressing mode fault. # Temporarily do the same thing for a SP destination operand # until a better solution can be figured out. # # v01-002 ljk0016 lawrence j. kenah 28-nov-1983 # algorithm was revised to work with digit pairs. overflow check # was modified to account for -2,147,483,648. # # v01-001 ljk0008 lawrence j. kenah 17-nov-1983 # the emulation code for cvtpl was moved into a separate module. #-- # include files:/* $psldef # define bit fields in psl * $srmdef # define arithmetic trap codes * cvtpl_def # bit fields in cvtpl registers * stack_def # stack usage for original exception */ # psect declarations: # begin_mark_point restart .text .text 2 .set table_size,0pc_table_base: .text 3handler_table_base: .text 1 .set restart_table_size,0restart_pc_table_base: .textmodule_base: #+ # functional description: # # the source string specified by the source length and source address # operands is converted to a longword and the destination operand is # replaced by the result. # # input parameters: # # r0 - srclen.rw length of input decimal string # r1 - srcaddr.ab address of input packed decimal string # r3 - dst.wl address of longword to receive converted string # # note that the cvtpl instruction is the only instruction in the # emulator package that has an operand type of .wx. this operand type # needs special treatment if the operand is to be written into a general # register. the following convention is established. if the destination # is anything other than a general register (addressing mode 5), then r3 # contains the address of the destination. if the destination is a # general register, then r3 contains the ones complement of the register # number. note that if this is interpreted as an address, then r3 points # to the last page of so-called s1 space, the reserved half of system # virtual address space. the algorithmic specification of this # convention is as follows. # # if r3 <31:04> nequ ^xfffffff # then # r3 contains the address of the destination operand # else # r3 contains the ones complement of the register number # of the single register to be loaded with the result # of the conversion # # that is, # # r3 = ffffffff ==> r0 <- result # r3 = fffffffe ==> r1 <- result # . # . # r3 = fffffff4 ==> r11 <- result # . # . # # note that any "s1 address" in r3 on input other than # ffffffff through fffffff0 will cause a length access # violation. # # output parameters: # # r0 = 0 # r1 = address of byte containing most significant digit of # the source string # r2 = 0 # r3 = 0 # # condition codes: # # n <- output longword lss 0 # z <- output longword eql 0 # v <- integer overflow # c <- 0 # # register usage: # # this routine uses r0 through r7. the condition codes are recorded # in r2 as the routine executes. In addition, r10 serves its usual # purpose by pointing to the access violation handler. #- .globl vax$cvtplL502: jmp vax$cvtpl_restart # Restart somewhere elsevax$cvtpl: bbs $(cvtpl_v_fpd+16),r0,L502# Branch if this is a restart # pushr $^m<r1,r4,r5,r6,r7,r10> # save some registers pushr $0x04f2 # establish_handler cvtpl_accvio movab cvtpl_accvio,r10 movpsl r2 # get current psl bicb2 $(psl$m_n|psl$m_z|psl$m_v|psl$m_c),r2 # clear condition codes clrl r6 # assume result is zero # roprand_check r0 # insure that r0 lequ 31 cmpw r0,$31 blequ 1f brw decimal_roprand1: movzwl r0,r0 beql 6f # all done if string has zero length # mark_point cvtpl_1,restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_1 - module_base .text 3 .word cvtpl_1 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_1_restart,restart_table_size .word Lcvtpl_1 - module_base .textLcvtpl_1: jsb decimal$strip_zeros_r0_r1 # eliminate leading zeros from input ashl $-1,r0,r0 # convert digit count to byte count beql 3f # skip loop if single digit # the first digit pair sets up the initial value of the result. # mark_point cvtpl_2,restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_2 - module_base .text 3 .word cvtpl_2 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_2_restart,restart_table_size .word Lcvtpl_2 - module_base .textLcvtpl_2: movzbl (r1)+,r5 # get first digit pair movzbl decimal$packed_to_binary_table[r5],r6 # convert to binary number # the sobgtr instruction at the bottom of the loop can be used to decrement # the byte count and test whether this is the special case of an initial # digit count of two or three. note that this loop does not attempt to # optimize the case where the v-bit is already set. brb 2f # join the loop at the bottom # mark_point cvtpl_3,restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_3 - module_base .text 3 .word cvtpl_3 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_3_restart,restart_table_size .word Lcvtpl_3 - module_base .textLcvtpl_3:1: movzbl (r1)+,r5 # get next digit pair movzbl decimal$packed_to_binary_table[r5],r5 # convert to binary number emul $100,r6,r5,r6 # blend this latest with previous result # check all of r7 and r6<31> for nonzero. unconditionally clear r6<31>. bbsc $31,r6,L15 # branch if overflow into r6<31> tstl r7 # anything into upper longword beql 2f # branch if okL15: bisb2 $psl$m_v,r2 # set saved v-bit2: sobgtr r0,1b # continue for rest of whole digit pairs # the final (least significant) digit is handled in a slightly different # fashion. this has an advantage in that the final overflow check is different # from the check that is made inside the loop. that check can be made quickly # without concern for the final digit special cases. # mark_point cvtpl_4,restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_4 - module_base .text 3 .word cvtpl_4 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_4_restart,restart_table_size .word Lcvtpl_4 - module_base .textLcvtpl_4:3: extzv $4,$4,(r1),r5 # get least significant digit emul $10,r6,r5,r6 # blend in with previous result # this overflow check differs from the one inside the loop in three ways. # # the check for nonzero r7 precedes the test of r6<31>. # # o the high order bit of r6 is left alone. (if overflow occurs, the # complete 32-bit contents of r6 need to be preserved.) # # o a special check is made to see if the 64-bit result is identically # equal to # # r6 = 80000000 # r7 = 00000000 # # o if this is true and the input sign is minus, then the overflow bit # needs to be turned off. this unusual result is passed to the following # code by means of a zero in r7. all other results cause nonzero r7 # (including the case where the v-bit was already set). #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -