📄 vaxfloat.s
字号:
# address access # # data type code definitions ## define typ_b 1 # byte# define typ_w 2 # word# define typ_l 3 # longword# define typ_q 4 # quadword# define typ_o 5 # octaword# define typ_f 6 # f_floating# define typ_d 7 # d_floating# define typ_g 8 # g_floating# define typ_h 9 # h_floating # # instruction type definitions for optimization check ## define it_d 1# define it_f 2# define it_g 4# define it_h 8# define it_x 0 # none #+ # functional description: # # this routine is entered in kernel mode through the scb vector for # the opcdec exception. it determines if the instruction that caused # the fault is one supported by this emulator. if so, the rest of the # emulation is carried out by an instruction-specific routine. if not, # control is transferred to the opcdec handler that is a part of the # vms executive to allow normal exception dispatching to take place. # # input parameters: # # 0(sp) - pc of faulting instruction # 4(sp) - psl at the time of the fault # # output parameters: # # the real output from this routine is the routine to which control # is passed, namely the routine that handles each separate instruction. #- .text .align 2 .globl vax$opcdec vax$opcdec: movq r0, -(sp) # save r0 and r1 # it is not clear whether the following prober is necessary. one approach is # that an inaccessible opcode would cause an access violation rather than # a reserved instruction exception. movl 8(sp), r0 # r0 contains the pc of the instruction # PUSHR; movl r0,-(sp); PRINTF(1, "pc that caused the exc %x\n"); POPR prober $0,$1,(r0) # insure that opcode can be read beql 6f movzbl (r0)+, r1 # get first opcode byte, increment "pc" # PUSHR; movl r1,-(sp); PRINTF(1, "the instruction to decoded %x\n"); POPR bbc r1, op_mask_1byte, 9f # test for opcode not emulated cmpb r1, $0xfd # is it a two-byte opcode? bneq 1f # skip if not prober $0,$1,(r0) # can second byte be read? beql 1f movzbl (r0), r1 # fetch second byte bbc r1, op_mask_2byte, 9f # test for opcode not emulated #+ # now the kernel stack looks as follows: # # 00(sp) - saved r0 # 04(sp) - saved r1 # 08(sp) - pc of instruction # 12(sp) - psl of instruction # # # switch stacks to that of the exception, push onto that stack the pc/psl. # push the psl with t, tp and fpd bits clear, the address of # emulate_fp, and then rei to emulate_fp. #- 1: # prober $0,$4,*$ctl$al_stack # is there a control region? # beql 9f # (not swapper,nullproc) extzv $psl$v_curmod,$psl$s_curmod,12(sp),r1 # get previous mode beql 2f # br if kernel, no stack change needed # assume psl$c_kernel eq 0 # assume pr$_esp eq psl$c_exec # assume pr$_ssp eq psl$c_super # assume pr$_usp eq psl$c_user mfpr r1, r0 # get address of stack of excpt mode probew $0,$8,-8(r0) # br if cannot copy to excpt mode stk beql 4f # cmpl r0,*$ctl$al_stack[r1] # top address of stack in range? # bgtru 4f # if gtru no. subl2 $8, r0 # get new low stack address cmpl $psl$c_user,r1 # previous mode user? beql 3f # if eql yes. # cmpl r0,*$ctl$al_stacklim[r1]# bottom address of stack in range? # bgequ 3f # if gequ yes.3: movq 8(sp), (r0) # push pc/psl mtpr r0, r1 # set stack pointer to new value # bicl2 $psl$m_tp|psl$m_tbit|psl$m_fpd,12(sp) # clear bits in psl bicl2 $0x48000010,12(sp) insv r1,$psl$v_prvmod,$psl$s_prvmod,12(sp) # set prvmod = curmod movab vax$$emulate_fp, 8(sp)# set entry address movq (sp)+, r0 # pop saved r0 and r1 rei # jump to emulate_fp brb 2f # join common code 6: brb 4f # chain branch for accvio test #+ # we come here if the previous mode is kernel, since we don't need to # switch modes. #- 2: movq (sp)+, r0 # pop saved r0 and r1 jmp vax$$emulate_fp # emulate the instruction #+ # if we don't handle the instruction, remove the things we pushed on the # stack and jump to the execption code that handles ss$_opcdec #- 9: movq (sp)+, r0 # restore r0-r1 jmp _Xprivinflt1 # reflect exception # if a probe of an outer access mode fails, then the exception is reported # as an access violation rather than as a reserved instruction. this allows # the stack expansion logic and other such things to be invoked without this # emulator worrying about such things. 4: movq (sp), -(sp) # move saved r0-r1 movl r0,12(sp) # store inaccessible stack address movq (sp)+,r0 # restore r0-r1 clrl (sp) # set mask to indicate a read jmp _Xprotflt # pass control to vms handler # # op_mask_1byte and op_mask_2byte are 256-bit bitmasks with # bits set corresponding to opcodes of instructions that # this emulator can handle. # op_mask_1byte: # mask for 1-byte opcodes (including fd) # fedcba9876543210fedcba9876543210 # .long b`00000000000000000000000000000000 # 00-1f.long 0x0 # .long b`00000000000000000000000000000000 # 20-3f.long 0x0 # .long b`00000000011111111111111111111111 # 40-5f.long 0x7fffff # .long b`00000000011111111111111111111111 # 60-7f.long 0x7fffff # .long b`00000000000000000000000000000000 # 80-9f.long 0x0 # .long b`00000000000000000000000000000000 # a0-bf.long 0x0 # .long b`00000000000000000000000000000000 # c0-df.long 0x0 # .long b`00100000000000000000000000000000 # e0-ff.long 0x20000000 op_mask_2byte: # mask for 2-byte opcodes (second byte index) # fedcba9876543210fedcba9876543210 # .long b`00000000000000000000000000000000 # 00-1f.long 0x0 # .long b`00000000000011000000000000000000 # 20-3f.long 0xc0000 # .long b`00000000011111111111111111111111 # 40-5f.long 0x7fffff # .long b`11110000011111111111111111111111 # 60-7f.long 0xf07fffff # .long b`00000011000000000000000000000000 # 80-9f.long 0x3000000 # .long b`00000000000000000000000000000000 # a0-bf.long 0x0 # .long b`00000000000000000000000000000000 # c0-df.long 0x0 # .long b`00000000110000000000000000000000 # e0-ff.long 0xc00000 # # vax$$emulate_fp - emulator entrance # # entered by branching # # parameters 0(sp) instruction pc # 4(sp) instruction psl # # discussion # # this routine provides a simple method of activating the # emulator. the pc and psl for the instruction being emulated # are pushed onto the stack and the routine is entered. the # routine simply allocates the simulated user stack space for # the emulator and calls the emulation procedure. # # notes: 1. the fpd bit may be set in the pushed psl. this # bit will only be interpreted during the emulation # of the polyx instructions where it is # interpreted as described in the vax system # reference manual. # # .globl vax$$emulate_fp vax$$emulate_fp: movab -4*(call_args-2)(sp),sp # allocate the parameter block calls $call_args,emulator # call the emulator jmp _Xprivinflt1 # shouldn't return here - # indicate opcdec as fallback # # # emulator - start instruction emulation # # parameters: ( described below ) # # discussion # # this routine initializes the emulator, processes the # instruction code, and passes control to the appropriate # instruction emulation routine. the parameter list consists of # call_args longwords of which only the last two have any # meaning. these parameters are the pc and psl for the emulation. # the position following the parameter list is the # user's stack pointer. the area covered by the parameter list # is used to emulate the top of the user's stack. # # when the routine is entered the calls instruction saves # the user's registers r0 to r11 in order and saves ap and fp # elsewhere in the frame. the routine extends the saved # registers by saving the user's ap, fp, sp, pc, and psl after # the saved register area (the last two are taken from the # parameter list). # # the local storage is allocated by extending the stack and # the register modification bytes are cleared (these bytes # record small changes to the register values). the cell mode # is set equal to the current access mode for use in probing # memory references. the alignment bits in the call frame and # the call parameter count are also saved so there is a safe # copies to use when processing unwinds. # # notes: 1. from the description of the way the simulated # register area is constructed, it is clear that # the length longword of the parameter list is # overwritten. all of the methods of leaving the # emulator put this longword back together. the # internal condition handler does this if it # detects an unwind. # # 2. here are some more details on the register change # bytes: until the very end of instruction processing # when the results are output, all of the changes # which occur to the registers are caused by adding # or subtracting small values to or from a register. # these changes are also recorded in a corresponding # register change byte so the register may be # restored to its original value if a fault occurs. # those instructions that save results in the # registers in order to be interruptable, use the fpd # bit in the psl to indicate that this has been done # so different logic should be used for restarting # the instruction after a fault. in this case the # change bytes should be cleared when fpd is set # except for the one for pc. # # 3. the location of the instruction being emulated is # stored in the return pc for the emulator's frame # so it may be easily located from the traceback # report if the emulator blows up. # emulator: # entrance .word 0x0fff # entry mask movab local_start(fp),sp # allocate the local storage clrb poly_x_flag(fp) # clear the poly_x_flag extzv $mask_align,$2,save_mask(fp),r0 # r0 = alignment bits movb r0,save_align(fp) # save them movb $call_args,save_parcnt(fp) # save the parameter count clrb flags(fp) # clear the flag bits movab cond_handler,handler(fp) # set up the condition handler clrq regmod_r0(fp) # clear register modification bytes clrq regmod_r8(fp) # clear register modification bytes movq save_ap(fp),reg_ap(fp) # move user's ap and fp into place movab 4*(call_args+1)(ap),reg_sp(fp) # move user's sp into place movq 4*(call_args-1)(ap),reg_pc(fp) # move pc and psl into place extzv $psl_cam,$2,psl(fp),r0 # r0 = user's access mode movb r0,mode(fp) # save it for probes movl reg_pc(fp),r11 # get instruction pc movl r11,save_pc(fp) # save pc in the return pc movab op_types(fp), op_index(fp)# initialize ptr to operand type codes movzbl (r11)+,r0 # get first opcode byte incl reg_pc(fp) # increment emulated pc incl regmod_pc(fp) # remember the increment bbc $psl_t,psl(fp),1f # check for t-bit bbss $psl_tp,psl(fp),1f # set tp if t set 1: bicl2 $pslm_v,psl(fp) # clear the v bit in the psl cmpb r0,$0xfd # two-byte instruction? bneq dispatch_1byte # skip if not movzbl (r11)+,r0 # get next opcode byte incl reg_pc(fp) # increment emulated pc incl regmod_pc(fp) # remember the increment brw dispatch_2byte # execute 2-byte opcode # # dispatch_1byte - branch to emulation routine for 1-byte opcode # # entered by branching # # r0 contains opcode # dispatch_1byte: caseb r0,$0x40,$(0x76-0x40) # from addf2 through cvtdf 1: .word inst_addf2-1b # 40 addf2 .word inst_addf3-1b # 41 addf3 .word inst_subf2-1b # 42 subf2 .word inst_subf3-1b # 43 subf3 .word inst_mulf2-1b # 44 mulf2 .word inst_mulf3-1b # 45 mulf3 .word inst_divf2-1b # 46 divf2 .word inst_divf3-1b # 47 divf3 .word inst_cvtfb-1b # 48 cvtfb .word inst_cvtfw-1b # 49 cvtfw .word inst_cvtfl-1b # 4a cvtfl .word inst_cvtrfl-1b # 4b cvtrfl .word inst_cvtbf-1b # 4c cvtbf .word inst_cvtwf-1b # 4d cvtwf .word inst_cvtlf-1b # 4e cvtlf .word inst_acbf-1b # 4f acbf .word inst_movf-1b # 50 movf .word inst_cmpf-1b # 51 cmpf .word inst_mnegf-1b # 52 mnegf .word inst_tstf-1b # 53 tstf .word inst_emodf-1b # 54 emodf .word inst_polyf-1b # 55 polyf .word inst_cvtfd-1b # 56 cvtfd .word 0f - 1b # 57 .word 0f - 1b # 58 adawi .word 0f - 1b # 59 .word 0f - 1b # 5a .word 0f - 1b # 5b .word 0f - 1b # 5c insqhi .word 0f - 1b # 5d insqti .word 0f - 1b # 5e remqhi .word 0f - 1b # 5f remqti .word inst_addd2-1b # 60 addd2 .word inst_addd3-1b # 61 addd3 .word inst_subd2-1b # 62 subd2 .word inst_subd3-1b # 63 subd3 .word inst_muld2-1b # 64 muld2 .word inst_muld3-1b # 65 muld3 .word inst_divd2-1b # 66 divd2 .word inst_divd3-1b # 67 divd3 .word inst_cvtdb-1b # 68 cvtdb .word inst_cvtdw-1b # 69 cvtdw .word inst_cvtdl-1b # 6a cvtdl .word inst_cvtrdl-1b # 6b cvtrdl .word inst_cvtbd-1b # 6c cvtbd .word inst_cvtwd-1b # 6d cvtwd .word inst_cvtld-1b # 6e cvtld .word inst_acbd-1b # 6f acbd .word inst_movd-1b # 70 movd .word inst_cmpd-1b # 71 cmpd .word inst_mnegd-1b # 72 mnegd .word inst_tstd-1b # 73 tstd .word inst_emodd-1b # 74 emodd .word inst_polyd-1b # 75 polyd .word inst_cvtdf-1b # 76 cvtdf 0: brw opcode_fault # unrecognized opcode # # dispatch_2byte - branch to emulation routine for 2-byte opcode # # entered by branching # # r0 contains second opcode byte # dispatch_2byte: caseb r0,$0x32,$(0x7f-0x32) # covers cvtdh through pushao 1: .word inst_cvtdh-1b # 32fd cvtdh .word inst_cvtgf-1b # 33fd cvtgf .word 0f - 1b # 34fd .word 0f - 1b # 35fd .word 0f - 1b # 36fd .word 0f - 1b # 37fd .word 0f - 1b # 38fd .word 0f - 1b # 39fd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -