📄 vaxeditpc.s
字号:
# from the vax$editpc routine. # # input parameters: # # r0 - current digit count in input string # r1 - address of next digit in input string # r2 - fill character # r3 - address of illegal pattern operator # r4 - sign character (stored in r2<15:8>) # r5 - address of next character to be stored in output character string # r9 - zero count (stored in r0<31:16>) # r11 - condition codes # # 00(sp) - saved r0 # 04(sp) - saved r1 # 08(sp) - saved r6 # 12(sp) - saved r7 # 16(sp) - saved r8 # 20(sp) - saved r9 # 24(sp) - saved r10 # 28(sp) - saved r11 # 32(sp) - return pc from vax$editpc routine # # output parameters: # # 00(sp) - offset in packed register array to delta pc byte # 04(sp) - return pc from vax$editpc routine # # some of the register contents are dictated by the vax architecture. # other register contents are architecturally described as "implementation # dependent" and are used to store the instruction state that enables it # to be restarted successfully and complete according to specifications. # # the following register contents are architecturally specified # # r0<15:00> - current digit count in input string # r0<31:16> - current zero count (from r9) # r1 - address of next digit in input string # r2<07:00> - fill character # r2<15:08> - sign character (from r4) # r3 - address of next pattern operator # r5 - address of next character in output character string # # the following register contents are peculiar to this implementation # # r2<23:16> - delta-pc (if initiated by exception) # r2<31:24> - delta srcaddr (current srcaddr minus initial srcaddr) # r4<07:00> - initial digit count (from saved r0) # r4<15:08> - saved condition codes (for easy retrieval) # r4<23:16> - state flags # state = editpc_2_restart # fpd bit is set # accvio bit is clear # r4<31:24> - unused for this exception (see access violations) # # editpc_2_restart is the restart code that causes the # instruction to be restarted at the top of the main loop. # It is the simplest point at which to resume execution after # an illegal pattern operator fault. # # the condition codes reported in the exception psl are also defined # by the vax architecture. # # psl<n> - source string has a minus sign # psl<z> - all digits are zero so far # psl<v> - nonzero digits have been lost # psl<c> - significance #- # assume editpc_l_saved_r1 eq <editpc_l_saved_r0 + 4>editpc_roprand_fault: # pushr $^m<r0,r1,r2,r3> # save current r0..r3 pushr $0x0f movq editpc_l_saved_r0(sp),r0 # retrieve original r0 and r1 movq r4,16(sp) # save r4 and r5 in right placeon stack # now start stuffing the various registers movw r9,editpc_w_zero_count(sp) # save r9 in r0<31:16> movb r4,editpc_b_sign(sp) # save r4 in r2<15:8> movb r0,editpc_b_inisrclen(sp) # save initial value of r0 subl3 r1,editpc_a_srcaddr(sp),r1 # calculate srcaddr difference movb r1,editpc_b_delta_srcaddr(sp) # store it in r4<15:8> movb r11,editpc_b_saved_psw(sp) # save condition codes movb $(editpc_m_fpd|editpc_2_restart),editpc_b_state(sp) # set the fpd bit # popr $^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> # load registers popr $0x0fff # pushl $<editpc_b_delta_pc!- # store delta-pc offset # pack_m_fpd> # indicate that fpd should be set pushl $(editpc_b_delta_pc|pack_m_fpd) # the following is admittedly gross. this is the only code path into # vax$roprand where the condition codes are significant. all other paths can # store the delta-pc offset without concern for its affect on condition # codes. fortunately, the popr instruction does not affect condition codes. pushl r0 # get a scratch register extzv $8,$4,r4,r0 # get codes from r4<11:8> bicpsw $(psl$m_n | psl$m_z | psl$m_v | psl$m_c )# clear the codes bispsw r0 # set relevant condition codes # popr $^m<r0> # restore r0, preserving psw popr $0x01 jmp vax$roprand # continue exception handling #- # functional description: # # this routine reports a reserved operand abort back to the caller. # # reserved operand aborts are trivial to handle because they cannot be # continued. there is no need to pack intermediate state into the # general registers. those registers that should not be modified by the # editpc instruction have their contents restored. control is then # passed to vax$roprand, which takes the necessary steps to eventually # reflect the exception back to the caller. # # the following conditions cause a reserved operand abort # # 1. input digit count gtru 31 # (this condition is detected by the editpc initialization code.) # # 2. not enough digits in source string to satisfy pattern operators # (this condition is detected by the eo_read routine.) # # 3. too many digits in source string (digits left over) # (this condition is detected by the eo$end routine.) # # 4. an eo$end operator was encountered while zero count was nonzero # (this condition is also detected by the eo$end routine.) # # input parameters: # # 00(sp) - saved r0 # 04(sp) - saved r1 # 08(sp) - saved r6 # 12(sp) - saved r7 # 16(sp) - saved r8 # 20(sp) - saved r9 # 24(sp) - saved r10 # 28(sp) - saved r11 # 32(sp) - return pc from vax$editpc routine # # output parameters: # # the contents of r0 through r5 are not important because the # architecture states that they are unpredictable if a reserved # operand abort occurs. no effort is made to put these registers # into a consistent state. # # r6 through r11 are restored to their values when the editpc # instruction began executing. # # 00(sp) - offset in packed register array to delta pc byte # 04(sp) - return pc from vax$editpc routine # # implicit output: # # this routine passes control to vax$roprand where further # exception processing takes place. #-editpc_roprand_abort: # popr $^m<r0,r1,r6,r7,r8,r9,r10,r11> # restore saved registers popr $0x0fc3 pushl $editpc_b_delta_pc # store delta-pc offset jmp vax$roprand # continue exception handling #+ # functional description: # # this routine receives control when an access violation occurs while # executing within the editpc emulator. this routine determines whether # the exception occurred while accessing the source decimal string, the # pattern stream, or the output character string. (this check is made # based on the pc of the exception.) # # if the pc is one that is recognized by this routine, then the state of # the instruction (character counts, string addresses, and the like) are # restored to a state where the instruction/routine can be restarted # after (if) the cause for the exception is eliminated. control is then # passed to a common routine that sets up the stack and the exception # parameters in such a way that the instruction or routine can restart # transparently. # # if the exception occurs at some unrecognized pc, then the exception is # reflected to the user as an exception that occurred within the # emulator. # # there are two exceptions that can occur that are not backed up to # appear as if they occurred at the site of the original emulated # instruction. these exceptions will appear to the user as if they # occurred inside the emulator itself. # # 1. if stack overflow occurs due to use of the stack by one of # the routines, it is unlikely that this routine will even # execute because the code that transfers control here must # first copy the parameters to the exception stack and that # operation would fail. (the failure causes control to be # transferred to vms, where the stack expansion logic is # invoked and the routine resumed transparently.) # # 2. if assumptions about the address space change out from under # these routines (because an ast deleted a portion of the # address space or a similar silly thing), the handling of the # exception is unpredictable. # # input parameters: # # r0 - value of sp when exception occurred # r1 - pc at which exception occurred # r2 - scratch # r3 - scratch # r10 - address of this routine (no longer needed) # # 00(sp) - value of r0 when exception occurred # 04(sp) - value of r1 when exception occurred # 08(sp) - value of r2 when exception occurred # 12(sp) - value of r3 when exception occurred # 16(sp) - return pc in exception dispatcher in operating system # # 20(sp) - first longword of system-specific exception data # . # . # xx(sp) - last longword of system-specific exception data # # the address of the next longword is the position of the stack when # the exception occurred. r0 locates this address. # # r0 -> xx+4(sp) - instruction-specific data # . - optional instruction-specific data # . - optional instruction-specific data # xx+<4*m>(sp) - return pc from vax$editpc routine (m is the number # of instruction-specific longwords) # # implicit input: # # it is assumed that the contents of all registers coming into this # routine are unchanged from their contents when the exception occurred. # (for r0 through r3, this assumption applies to the saved register # contents on the top of the stack. any modification to these four # registers must be made to their saved copies and not to the registers # themselves.) # # it is further assumed that the exception pc is within the bounds of # this module. (violation of this assumption is simply an inefficiency.) # # finally, the macro begin_mark_point should have been invoked at the # beginning of this module to define the symbols # # module_base # pc_table_base # handler_table_base # table_size # # output parameters: # # if the exception is recognized (that is, if the exception pc is # associated with one of the mark points), control is passed to the # context-specific routine that restores the instruction state to a # uniform point from which the editpc instruction can be restarted. # # r0 - value of sp when exception occurred # r1 - scratch # r2 - scratch # r3 - scratch # r10 - scratch # # vax$editpc is different from the other emulated instructions in that # it requires intermediate state to be stored in r4 and r5 as well as r0 # through r3. this requires that r4 and r5 also be saved on the stack so # that they can be manipulated in a consistent fashion. # # 00(sp) - value of r0 when exception occurred # 04(sp) - value of r1 when exception occurred # 08(sp) - value of r2 when exception occurred # 12(sp) - value of r3 when exception occurred # 16(sp) - value of r4 when exception occurred # 20(sp) - value of r5 when exception occurred # 24(sp) - value of r0 when exception occurred # 28(sp) - value of r1 when exception occurred # 32(sp) - value of r2 when exception occurred # 36(sp) - value of r3 when exception occurred # 40(sp) - return pc in exception dispatcher in operating system # etc. # # r0 -> zz(sp) - instruction-specific data begins here # # if the exception pc occurred somewhere else (such as a stack access), # the saved registers are restored and control is passed back to the # host system with an rsb instruction. # # implicit output: # # the register contents are modified to put the intermediate state of # the instruction into a consistent state from which it can be # continued. any registers saved by the vax$editpc routine are # restored. #-editpc_accvio: movq r4,-(sp) # store r5 and r4 on the stack movq 16(sp),-(sp) # ... and another copy of r3 and r2 movq 16(sp),-(sp) # ... and another copy of r1 and r0 clrl r2 # initialize the counter pushab module_base # store base address of this module subl2 (sp)+,r1 # get pc relative to this base1: cmpw r1,pc_table_base[r2] # is this the right pc? beql 3f # exit loop if true aoblss $table_size,r2,1b # do the entire table # if we drop through the dispatching based on pc, then the exception is not # one that we want to back up. we simply reflect the exception to the user.2: addl2 $16,sp # discard duplicate saved r0 .. r3 movq (sp)+,r4 # restore r4 and r5 # popr $^m<r0,r1,r2,r3> # restore saved registers popr $0x0f rsb # return to exception dispatcher # the exception pc matched one of the entries in our pc table. r2 contains # the index into both the pc table and the handler table. r1 has served # its purpose and can be used as a scratch register.3: movzwl handler_table_base[r2],r1 # get the offset to the handler jmp module_base[r1] # pass control to the handler # in all of the instruction-specific routines, the state of the stack # will be shown as it was when the exception occurred. all offsets will # be pictured relative to r0. #+ # eo_read packing routine # # functional description: # # this routine executes if an access violation occurred in the eo_read # subroutine while accessing the input packed decimal string. # # input parameters: # # r0 - address of top of stack when access violation occurred # # 00(r0) - return pc to caller of eo_read # 04(r0) - return pc to main vax$editpc control loop # 08(r0) - saved r0 # 12(r0) - saved r1 # etc. # # output parameters: # # if the caller of this routine a recognized restart point, the restart # code is stored in editpc_b_state in the saved register array, the # psuedo stack pointer r0 is advanced by one, and control is passed to # the general editpc_pack routine for final exception processing. # # r0 is advanced by one longword # # 00(r0) - return pc to main vax$editpc control loop # 04(r0) - saved r0 # 08(r0) - saved r1 # etc. # # editpc_b_state(sp) - code that uniquely determines the caller # of eo_read when the access violation was detected. # # if the caller's pc is not recognized, the exception is dismissed from # further modification. #-read_1:read_2: clrl r2 # set table index to zero pushab module_base # prepare for pic arithmetic subl3 (sp)+,(r0)+,r1 # r1 contains relative pc subl2 $3,r1 # back up over bsbw instruction4: cmpw r1,restart_pc_table_base[r2] # check next pc offset beql 5f # exit loop if match aoblss $restart_table_size,r2,4b # check for end of loop # if we drop through this loop, we got into the eo_read subroutine from # other than one of the three known call sites. we pass control back to # the general exception dispatcher. brb 2b # join common code to dismiss exception # store the restart code appropriate to the return pc and join common code to # store the rest of the instruction state into the saved register array.5: addb3 $1,r2,editpc_b_state(sp) # restart code base is 1, not 0 incw editpc_w_srclen(sp) # digit never got read brb 7f # join common code #+ # packing routine for storage loops # # functional description:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -