📄 vaxfloat.s
字号:
# 2. if the frame is moved to a higher address, then # the saved ap and fp are changed to the values of # the emulated registers. the reason for this is # that the move may overlay a valid frame so it is # assumed that the user's ap and fp have been changed # by the instruction to information about a new valid # frame. the implementor thinks that all of this is # pretty strange but if the program will work with # the hardware it will still work with the emulator. # test_frame: # entrance pushl $0 # push a zero subl3 r0,reg_sp(fp),r0 # compute pushed information address bicl2 $3,r0 # align the value movab local_end(fp),r1 # r1 = end of local storage cmpl r0,r1 # does push extend below the frame ? bgequ 2f # no - bypass bicl3 $3,sp,r3 # r3 = aligned stack pointer subl2 $24,r3 # adjust for additional pushes movl r0,r2 # r2 = address following moved frame cmpl r2,r3 # does it extend into the frame ? blequ 3f # no - bypass movl r3,r2 # yes - use address below the frame brb 3f # bypass 2: movab frame_end+1027(fp),r2 # r2 = last possible parameter end cmpl r0,r2 # does the push end above it ? blequ 5f # no - bypass movq reg_ap(fp),save_ap(fp) # change the saved ap and fp bicl3 $3,r0,r2 # r2 = aligned user stack pointer 3: subl2 r1,r2 # r2 = distance of the move pushl r2 # push the quantity pushab (sp)[r2] # push the modified sp pushab (fp)[r2] # push the modified fp pushab (ap)[r2] # push the modified ap pushab save_align(fp)[r2] # push the new alignment bits location pushab save_parcnt(fp)[r2] # push the new parameter count address movab frame_end+4(fp)[r2],r3 # r3 = new frame end + 4 location subl3 r3,r0,r3 # r3 = distance to user's sp ashl $-2,r3,-(sp) # push the new parameter count subl3 sp,r1,r0 # r0 = number of bytes to move movl sp,r1 # r1 = location of bytes to move tstl r2 # will we extend the stack ? bgeq 4f # no - skip addl2 r2,sp # yes - extend the stack pointer 4: movc3 r0,(r1),(r1)[r2] # move the frame cvtlb (sp)+,*(sp)+ # store the new parameter count clrb *(sp)+ # clear the new alignment bits popr $0x7000 # switch to the new frame ^m<ap,fp,sp> 5: popr $0x1 # r0 = distance frame was moved rsb # return # # # cond_handler - internal condition handler # # parameters: p1 = signal array location # p2 = mechanism array location # # returns with r0 = condition response # # discussion # # this routine is the internal condition handler for the # emulator. since the emulator does not make constructive use # of exceptions in its main procedure, this routine requests # resignaling of all conditions it intercepts. # # if the condition is ss$_unwind which indicates that an # unwind is about to take place, then it restores the argument # count longword in the parameter list for the procedure so the # unwind will work properly. # cond_handler: # entrance .word 0 # entry mask movq 4(ap),r0 # r0,r1 = condition array locations # cmpcond ss$_unwind,4(r0) # is this an unwind ? cmpzv $3,$26,4(r0),$ss$_unwind bneq 1f # no - bypass movl 4(r1),r0 # r0 = frame location movzbl save_align(r0),r1 # r1 = safe copy of alignment bits movzbl save_parcnt(fp),-(sp) # push the argument count insv r1,$mask_align,$2,save_mask(r0) # store align bits in frame addl2 r1,r0 # add to the frame location movl (sp)+,frame_end(r0) # store the argument count 1: movzwl $ss$_resignal,r0 # resignal the condition ret # return # # **************************************************************** # * * # * * # * instruction emulation routines * # * * # * * # **************************************************************** # # # introduction # ------------ # # following are the routines for emulating the individual # new instructions. there is one routine for each instruction # but the structure of most of these routines is extremely # simple so we have included all of the descriptive information # here rather than duplicating it for each routine. special # discussions are given for those instructions or families of # instructions which do not quite fit into the general patterns. # # the routines themselves have been written so that they # will be easy to follow. because of this the temptation to # remove a considerable amount of duplicated code has been # staunchly resisted. # # the emulation routines have names which are of the form # "inst_mnemonic", are entered by branching from the routine # emulator, and when instruction is complete the routines branch # to normal_exit. when exceptions occur, then flow of control is # somewhat more complicated and is described below. # # # operand processing # ------------------ # # the first step for each of the instructions is to process # the instruction operands (this process is inhibited only for # polyx when fpd is set in the psl). this is done by # calling the operand scanning routines for each operand and by # saving the operands values (for read and modify access # operands) and operand addresses (for write, modify, and # address, access operands) in the special areas of the frame # allocated for that purpose. floating values of all types that # are input are converted to our internal floating format by the # unpack routines which are described below. # # # instruction emulation # --------------------- # # after all of the operands have been processed, the action # of the instruction is performed usually by calling one of the # arithmetic routines. for many of the move and convert # instructions no special emulation action is necessary since # everything is done by the pack and unpack routines. all of the # floating arithmetic is performed using our internal floating # representation. # # # storing the results # ------------------- # # the last step of instruction emulation is storing the # resulting values and updating the condition codes. the values # are stored in the order in which their corresponding operands # occur so the instruction is emulated properly when the write # or modify access operands overlap. floating values are # converted from the internal floating representation to the # target representation by one of the pack routines described # below. after the results are output, the condition codes in # the emulated psl are updated. this order of operation is # important since the pack routines may convert very small # nonzero values to zero values if an underflow occurs and fu is # clear in the psl. when the instruction emulation is complete # the routine branches to normal_exit. # # # exceptions # ---------- # # except for the integer overflow trap, all of the # exceptions that the emulator checks for are faults. when # faults occur the emulator restores everything to a state in # which the instruction can be restarted and signals the fault. # for the integer overflow trap, the instruction is run to # completion, possibly outputing a truncated result, and the # trap is signaled. here we describe how instruction emulation # is organized so this can be accomplished. further information # can be found in the essay on exception processing which # appears below. # # # faults # # until the results of an instruction are output, all of the # changes which take place to any register are additions and # subtractions of small integers. these changes are also # recorded in the change bytes corresponding to the registers. # therefore the only requirement necessary for correct fault # processing is to insure that all fault detection takes place # before any of the instruction results are output (actually, # things are a little more complicated for polyx). # this is done by making the result outputing steps the last # part of instruction emulation. in this way fault detection # can be placed anywhere in the emulator it is convenient rather # than requiring close synchronization with the instruction # emulation logic. for this reason direct processing of faults # (rather than, say, returning status codes) appears throughout # the common emulator subroutines. # # the architecture makes no special requirements on the # the condition codes generated by a fault except that they # be sufficient for correctly restarting the instruction. in # general, the v bit is cleared by emulator on entry to an # instruction emulation routine since the bit is used for # detecting integer overflow traps (see below). none of the # other condition bits is altered until the results are output # at the end of instruction emulation. consequently all of the # other condition bits are preserved into faults. (with the # present set of emulated instructions the only preservation # requirement is that the c bit be preserved on faults by the # acbx instructions.) # # # integer overflow traps # # when a integer overflow is detected (either in a common # subroutine or in the instruction emulation routine) the v # bit is set in the emulated condition codes and the value is # truncated. everything proceeds normally until control reaches # normal_exit where the v and iv bits in the emulated psl are # checked. if both are set then an integer overflow trap is # signaled. # # # access modes and access violations # # this version of the emulator has been designed to operate # at the same access mode as the instruction being emulated. # however most of the instruction emulation logic has been # designed to operate at any access mode that is not less # privleged than that of the instruction (exceptions: the logic # for getting in, the logic for getting out, and the exception # signaling logic). all attempts to access memory on behalf of # the instruction are probed using the access mode contained in # the local cell mode. this is normally set to the current # access mode but may be set to some less privleged access mode. # because this version of the emulator operates on the user # stack it is not necessary to probe stack operations, however, # these probes are still done to insure that the code will # remain usable for different access modes. # # # notes on the acbx instructions # --------------------------------------- # # for these instructions the operands are processed, the # step is added to the index, and the sum is packed and output. # afterwards the sum is unpacked again and compared with the # limit, the type of comparison depending on the sign of the # step. the packing and unpacking is necessary to truncate the # sum to the correct number of bits, to perform any rounding, # and to check for underflow or overflow exceptions. if the # branch is to be taken, the branch destination is moved into # the emulated pc. # # # notes on the emodx instructions # ----------------------------------------- # # for these instructions the first two operands are a # floating value of the appropriate type and a word containing # some extension bits. when the extension bits are picked up # they are stored in the correct position of the unpacked first # operand. the remaining operands are scanned and flag bits 1 # and 7 are used to remember which output operands are in the # registers. the multiply is then performed using the proper # arithmetic routine and the product is truncated to the correct # number of bits. next the integer part is extracted and saved # in an internal cell while the fraction part is extracted and # packed. next any register output operands are output and # the routine test_frame is called to insure that the user's # stack pointer is within the parameter area. next any output # operands in memory are output with stores into the emulator's # working storage disabled .if both output operands are in the # same type of storage, then the integer part is output before # the fraction part. this complicated method of outputing the # results is necessary because one of the register operands may # contain sp and extend the user's stack into the emulator's # working storage. the call to test_frame will move the frame # if this occurs so if the other operand will be stored into # memory properly if it is not below the user's stack pointer. # # # notes on the polyx instructions # ----------------------------------------- # # these instructions have especially complicated emulation # routines because they do a lot, have a large number of # implicit inputs and outputs, and are intended to be resumed # instead of restarted when faults occur. for this reason we # describe the action of the instruction emulation routines in # some detail. # # these instructions can be thought as having two states. # in the first of these states no unreversable changes have # been made to the registers so if a fault occurs the # instruction can be restarted. the instruction remains in this # state until all of the operands have been processed and the # first coefficient has been validated. after this point the # instruction saves various things in the registers r0-r5 (and # on the stack for polyh) so the instruction can no longer be # restarted but the information saved is sufficient for resuming # the instruction after a fault. when this second state is # reached the fpd bit is set in the psl so the when the # instruction emulation routine is entered for resuming the # instruction it will know enough to do so. # # following is an outline of the steps in the emulation of # the two instructions. the text generally describes polyg and # the differences for polyh are noted in parentheses. # # # 1. this is the first step for the instruction emulation. # if the fpd bit is clear in the psl then control passes # to step 2. otherwise the following actions which are # concerned with restarting the instruction take place: # # the length of the instruction operands is retrieved # from the high order three bytes of the user's r2 (r4 # for polyh) and added to the current pc and to the # change byte for the pc. if the instruction terminates # the pc will be positioned following the instruction # and if the instruction faults it will be reset to the # location of the instruction. # # the result so far is unpacked from r0-r1 (r0-r3 for # polyh) and the unpacked value is stored in operand2. # the condition codes are set to describe this value. # # the argument is unpacked from r4-r5 (from a stacked # octaword for polyh, which is probed) and the unpacked # value is stored in operand3. # # the remaining coefficient count in the low order byte # of r2 (r4 for polyh) is checked for validity. # # finally control passes to step 3. # # # 2. this step performs all of the processing for initial # entry to the instruction. # # the first operand is processed and the unpacked # argument is saved in operand3. # # the second operand is processed and the degree is # checked for validity and the value is saved # temporarily in address1. # # the third operand is processed and the address of the # coefficient table is saved. the first coefficient is # probed, unpacked, and saved in operand2. # # if the instruction is polyh then the user's sp is # decremented by 16 (and so is the change byte) and # the argument value in operand3 is packed and output # to the allocated stack area. (if a fault occurs before # fpd is set then sp will be reinitilized properly.) # # the coefficient in operand2 is packed and stored in # the user's registers r0-r1 (r0-r4 for polyh), the # address of the remaining coefficients is stored in the # user's r4 (r6 for polyh), the degree is stored in the # low order byte of the user's r2 (r4 for polyh), and # the length of the instruction operands (the pc change # byte minus two) is saved in the upper three bytes of # that register. the condition codes are set based on # the value in operand2. # # all of the change bytes except that for pc are cleared # and the bit fpd is set in the emulated psl. # # if the instruction is polyg then the argument in # operand3 is packed and saved in the user's r4-r5. # # control passes to step 3. # # # 3. this step performs the basic polynomial evaluation # iteration. # # if the remaining coefficient count in the low order # byte of the user's r2 (r4 for polyh) is zero then # control passes to step 4. # # the value so far in operand2 and the argument in # operand3 are multiplied and the unnormalized product # is truncated to 63 (127 for polyh) bits and stored # in operand1. the truncation is performed by clearing # the low order bit of the 64 (128 for polyh) bit # product returned by the multiply routine. # # the coefficient addressed by the user's r3 (r5 for # polyh) is probed and unpacked to operand2. the result # is then added to operand1. # # the new value so far in operand1 is packed and stored # in the user's r0-r1 (r0-r3 for polyh). the condition # codes are set based on this value. the value is then # unpacked and stored in operand2. # # the remaining coefficient count in the low order byte # of r2 (r4 for polyh) is decremented and the pointer to # the next coeffiecient in r3 (r5 for polyh) is # incremented to point to the next coefficient. # # control then passes to the beginning of this step. # # # 4. this step performs the termination of the instruction. # # the register r2 (r4 for polyh) which contains the # instruction length and the coefficient count is # cleared. # # if the instruction was polyg then the registers r4-r5 # which contained the argument value are cleared.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -