📄 vaxcvtpl.s
字号:
# note that the check for v-bit previously set is the single additional # instruction that must execute in the normal (v-bit clear) case to test # for the extraordinarily rare case of -2147483648. tstl r7 # overflow into second longword? bneq L36 # branch if overflow bbs $psl$v_v,r2,L33 # set r7 to nonzero if v-bit already set cmpl r6,$0x80000000 # peculiar check for r6<31> neq zero blssu 4f # branch if no overflow at all beql L36 # leave r7 alone in special caseL33: incl r7 # set r7 to nonzero in all other casesL36: bisb2 $psl$m_v,r2 # set saved v-bit # all of the input digits have been processed, get the sign of the input # string and complete the instruction processing. # mark_point cvtpl_5,restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_5 - module_base .text 3 .word cvtpl_5 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_5_restart,restart_table_size .word Lcvtpl_5 - module_base .textLcvtpl_5:4: bicb3 $0x0f0,(r1),r5 # get sign "digit" caseb r5,$10,$15-10 # dispatch on sign L1: .word 6f-L1 # 10 => + .word 5f-L1 # 11 => - .word 6f-L1 # 12 => + .word 5f-L1 # 13 => - .word 6f-L1 # 14 => + .word 6f-L1 # 15 => + # note that negative zero is not a problem in this instruction because the # longword result will simply be zero, independent of the input sign.5: mnegl r6,r6 # change sign on negative input tstl r7 # was input -2,147,483,648? bneq 6f # nope, leave v-bit alone bicb2 $psl$m_v,r2 # clear saved v-bit6: movl (sp)+,r1 # restore original value of r1 clrq -(sp) # set saved r2 and r3 to zero # if r3 contains the ones complement of a number between 0 and 15, then the # destination is a general register. special processing is required to # correctly restore registers, store the result in a register, and set the # condition codes. mcoml r3,r7 # set up r7 for limit check with case casel r7,$0,$15 - 0 # see if r7 contains a register numberL2: .word L0-L2 # r0 -- store into r0 via popr .word L0-L2 # r1 -- store into r1 via popr .word L110-L2 # r2 -- store in saved r2 on stack .word L110-L2 # r3 -- store in saved r3 on stack .word L110-L2 # r4 -- store in saved r4 on stack .word L110-L2 # r5 -- store in saved r5 on stack .word L110-L2 # r6 -- store in saved r5 on stack .word L110-L2 # r7 -- store in saved r5 on stack .word L0-L2 # r8 -- store into r8 via popr .word L0-L2 # r9 -- store into r8 via popr .word L120-L2 # r10 -- store into r8 via popr .word L0-L2 # r11 -- store into r8 via popr .word L0-L2 # ap -- store into r8 via popr .word L0-L2 # fp -- store into r8 via popr # the result of specifying pc as a destination operand is defined to be # unpredictable in the vax architecture. in addition, it is difficult (but # not impossible) for this emulator to modify sp because it is using the # stack for local storage. we will generate a reserved addressing mode fault # if pc is specified as the destination operand. we will also temporarily # generate a reserved addressing mode fault if sp is specified as the # destination operand. .word L0-cvtpl_radrmod # sp -- reserved addressing mode .word L0-cvtpl_radrmod # pc -- reserved addressing mode # if we drop through the case instruction, then r3 contains the address of # the destination operand. this includes system space addresses in the range # c0000000 to ffffffff other than the ones complements of 0 through 15 # (fffffff0 to ffffffff). the next instruction will cause an access violation # for all such illegal system space addresses. # mark_point cvtpl_6, restart .text 2 .set table_size,table_size + 1 .word Lcvtpl_6 - module_base .text 3 .word cvtpl_6 - module_base .text 1 .set restart_table_size,restart_table_size+1 .set cvtpl_6_restart,restart_table_size .word Lcvtpl_6 - module_base .textLcvtpl_6: movl r6,(r3) # store result and set condition codes # this is the exit path for this routine. the result has already been stored. # the condition codes are set and the saved registers restored. the bicpsw # instruction is necessary because the various instructions that stored the # result (movl, pushl, etc.) do not affect the c-bit and the c-bit must be # clear on exit from this routine.7: bicpsw $psl$m_c # insure that c-bit is clear on exit bispsw r2 # set saved v-bit bbs $psl$v_v,r2,L75 # step out of line for overflow check # popr $^m<r2,r3,r4,r5,r6,r7,r10> # restore saved registers and clear popr $0x04fc # r2 and r3 rsbL72: bicpsw $(psl$m_n|psl$m_z|psl$m_v|psl$m_c) # clear condition codes bispsw r3 # set relevant condition codes # popr $^m<r2,r3,r4,r5,r6,r7,r10> # restore saved registers popr $0x04fc rsb # if the v-bit is set and decimal traps are enabled (iv-bit is set), then # a decimal overflow trap is generated. note that the iv-bit can be set in # the current psl or, if this routine was entered as the result of an emulated # instruction exception, in the saved psl on the stack.L75: movpsl r3 # save current condition codes bbs $psl$v_iv,r2,L78 # report exception if current iv-bit set movab vax$exit_emulator,r2 # set up r2 for pic address comparison cmpl r2,(4*7)(sp) # is return pc eqlu vax$exit_emulator ? bnequ L72 # no. simply return v-bit set bbc $psl$v_iv,((4*(7+1))+exception_psl)(sp),L72 # only return v-bit if iv-bit is clear bicpsw $(psl$m_n|psl$m_z|psl$m_v|psl$m_c) # clear condition codes bispsw r3 # set relevant condition codesL78: # popr $^m<r2,r3,r4,r5,r6,r7,r10># otherwise, restore the registers popr $0x04fc # ... drop into integer_overflow #+ # this code path is entered if the result is too large to fit into a longword # and integer overflow exceptions are enabled. the final state of the # instruction, including the condition codes, is entirely in place. # # input parameter: # # (sp) - return pc # # output parameters: # # 0(sp) - srm$k_int_ovf_t (arithmetic trap code) # 4(sp) - final state psl # 8(sp) - return pc # # implicit output: # # control passes through this code to vax$reflect_trap. #-integer_overflow: movpsl -(sp) # save final psl on stack pushl $srm$k_int_ovf_t # store arithmetic trap code jmp vax$reflect_trap # report exception #+ # the destination address is a general register. r3 contains the ones # complement of the register number of the general register that is to be # loaded with the result. note that the result must be stored in such a way # that restoring the saved registers does not overwrite the destination. # # the algorithm that accomplishes a correct store of the result with the # accompanying setting of the condition codes is as follows. # # if the register is in the range r2 through r7 or r10 # then # store the result on the stack over that saved register # (note that this store sets condition codes, except the c-bit) # else # construct a register save mask from the register number # store result on the top of the stack # (note that this store sets condition codes, except the c-bit) # popr the result using the mask in r3 # endif # restore saved registers #- # r7 contains 0, 1, 8, 9, 10, 11, 12, 13, or 14. we will use the bit number # to create a register save mask for the appropriate register. note that $1 # is the source operand and r7 is the shift count in the next instruction.L0: ashl r7,$1,r3 # r3 contains mask for single register pushl r6 # store result and set condition codes popr r3 # restore result into correct register brb 7b # restore r2 through r7 and return # r7 contains 2, 3, 4, 5, 6, or 7L110: movl r6,-8(sp)[r7] # store result over saved register brb 7b # restore r2 through r7 and return # r7 contains a 10L120: movl r6,24(sp) # Store result over saved register brb 7b # Restore register and return #- # functional description: # # this routine receives control when a digit count larger than 31 # is detected. the exception is architecturally defined as an # abort so there is no need to store intermediate state. the digit # count is made after registers are saved. these registers must be # restored before reporting the exception. # # input parameters: # # 00(sp) - saved r1 # 04(sp) - saved r4 # 08(sp) - saved r5 # 12(sp) - saved r6 # 16(sp) - saved r7 # 20(sp) - saved r10 # 24(sp) - return pc from vax$cvtpl routine # # output parameters: # # 00(sp) - offset in packed register array to delta pc byte # 04(sp) - return pc from vax$cvtpl routine # # implicit output: # # this routine passes control to vax$roprand where further # exception processing takes place. #-decimal_roprand: # popr #^m<r1,r4,r5,r6,r7,r10> # restore saved registers popr $0x04f2 pushl $cvtpl_b_delta_pc # store offset to delta pc byte jmp vax$roprand # pass control along #- # functional description: # # this routine receives control when pc or sp is used as the destination # of a cvtpl instruction. the reaction to this is not architecturally # defined so we are somewhat free in how we handle it. we currently # generate a radrmod abort with r0 containing the correct 32-bit result. # in the future, we may make this instruction restartable following this # exception. # # input parameters: # # r0 - zero # r1 - address of source decimal string # r2 - contains overflow indication in r2<psl$v_v> # r3 - register number in ones complement form # r3 = -15 => pc was destination operand # r3 = -14 => sp was destination operand # r4 - scratch # r5 - scratch # r6 - correct 32-bit result # r7 - scratch # # 00(sp) - saved r2 (contains zero) # 04(sp) - saved r3 (contains zero) # 08(sp) - saved r4 # 12(sp) - saved r5 # 16(sp) - saved r6 # 20(sp) - saved r7 # 24(sp) - return pc from vax$xxxxxx routine # # output parameters: # # r0 - correct 32-bit result # # r1, r2, and r3 are unchanged from their input values. # # r4 through r7 are restored from the stack. # # 00(sp) - offset in packed register array to delta pc byte # 04(sp) - return pc from vax$xxxxxx routine # # implicit output: # # this routine passes control to vax$radrmod where further # exception processing takes place. #-cvtpl_radrmod: addl2 $8,sp # discard "saved" r2 and r3 movl r6,r0 # remember final result # popr #^m<r4,r5,r6,r7> # restore saved registers popr $0x0f0 pushl $cvtpl_b_delta_pc # store offset to delta pc byte jmp vax$radrmod # pass control along #+ # functional description: # # this routine receives control when an access violation occurs while # executing within the vax$cvtpl emulator routine. # # the routine header for ashp_accvio in module vax$ashp contains a # detailed description of access violation handling for the decimal # string instructions. this routine differs from most decimal # instruction emulation routines in that it preserves intermediate # results if an access violation occurs. this is accomplished by # storing the number of the exception point, as well as intermediate # arithmetic results, in the registers r0 through r3. # # input parameters: # # see routine ashp_accvio in module vax$ashp # # output parameters: # # see routine ashp_accvio in module vax$ashp #-cvtpl_accvio: clrl r2 # initialize the counter pushab module_base # store base address of this module pushab module_end # store module end address jsb decimal$bounds_check # check if pc is inside the module
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -