Double Machine Problem 5, due Dec 7

Part of the homework for 22C:60, Fall 2008
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Submit the source file mp5.a for your solution using the submit command, documented at:
-- http://www.divms.uiowa.edu/help/msstart/submit.html

The Problem

The Hawk has several undefined instructions that, if used, cause an illegal instruction trap. The following is one of these, with documentation lifted from the Hawk instruction set summary:

 _______________   _______________
|_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_|
|       |  dst  | |       |  src  |

 0 0 0 1           1 0 0 0          --

Consider the following proposed instruction:

 _______________   _______________
|_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_|
|       | dst |s| |       |  cnt  |

 0 0 0 1           1 0 0 0          -- double precision shift

       dst -- an even numbered register from 2 to 14.
              Therefore, the least significant bit is always zero,
              so it is available to use as the s field.

       s   -- the direction to shift.
              0 means left shift, 1 means right shift.

       cnt -- the distance to shift, from 1 to 16 bits.
              A count of 0 means 16 bits, while values from
              1 to 15 have the usual meanings.

Here are some macros that could be added to hawk.macs to support this new instruction, presenting it as a pair of instructions, DSL for double shift left, and DSR for double shift right:

        MACRO qEVENNZq  =x
          IF (ABS(x) = 0)
            ERROR register R0 not allowed
          ELSEIF ((ABS(x) & 1) = 1)
            ERROR odd registers not allowed
          ENDIF
        ENDMAC

        MACRO DSL =dst,=cnt  ; double shift left
          qEVENNZq dst
          qSPECREGq #1080,dst,cnt,0
        ENDMAC

        MACRO DSR =dst,=cnt  ; double shift right
          qEVENNZq dst
          qSPECREGq #1180,dst,cnt,0
        ENDMAC

Before setting out to implement a new instruction in hardware, the hardware designers would like to have an assessment of how that instruction helps in real applications. So, they ask the software people to test it. This means writing test programs that use it, but it also means weriting code to emulate this instruction so the test programs can be run.

The Assignment

Write a trap handler for the illegal instruction trap that will implement this instruction. For all other opcodes, the handler should behave as the exiting handler behaves.

We strongly recommend incremental development! You have two central issues here: First to write the trap handler, second to write the emulation code to test it.

Half credit will be given for cleanly formatted properly commented source code, regardless of whether it works correctly, so long as it covers all of the required routines. Half credit will be given for the correct operation of your code, regardless of looks.

Your solution should include just the trap handler. It can be assembled together with the existing hawk monitor and with the program under test (the main program). Here is a skeleton of an appropriate solution, minus most of the comments and many other key pieces:

        ; save area used by instruction trap handler
                COMMON  INSTSAVE,SAVESIZE

        ; code to install instruction trap handler
        LCSAVE  =       .
        .       =       INSTRTRAP       ; the followin code is 16 bytes
                CPUSET  R2,TSV          ;  2    save R2
                LIL     R2,SAVEAREA     ;  4    make savearea pointer
                STORE   R1,R2,svR1      ;  4    save R1
                LIL     R1,HANDLER      ;  4    get pointer to handler
                JUMPS   R1              ;  2    go to handler
        .       =       LCSAVE

        ; remainder of instruction trap handler
        HANDLER:

Note: The linker is unaware of any linkage between your code and the test program. The linker loads your piece of the trap vector over the top of the default trap vector provided by the Hawk monitor. Control transfers to your code by traps raised by your test program. You will need to link your code and your test program, as in MP4, but as in MP4, you only submit your code, not the test program.


Questions and Answers

I found that I cannot use the file exception.h. Do we need to use that file in mp5?

No.

In chapter 13 of textbook, there is an example of checking what instruction caused the trap. Can you tell me what is PROGERR stands for?

It is the program error exception. But you do not need to raise any exceptions here, because the assignment said "For all other opcodes, the handler should behave as the exiting handler behaves."

The existing handler in the Hawk monitor does not raise exceptions, it just prints diagnostic output and then terminates. You are free to borrow any code from the hawk monitor you might find useful. Please comment borrowed code as such. is useful.

"For all other opcodes, the handler should behave as the exiting handler behaves." For my simple test program (my mp5 test program without linking to my trap handler), the "default exit behavior" prints the following:

Instruction Trap.  Trap PC = #00001018
                   Trap MA = #00010000
                   Trap PSW= #00010008

#1018 is indeed the PC of the bad opcode instruction, but the MA and PSW confuse me. Looking through the monitor code, I (believe I) found that these are pointers MA and the PSW (MA is at #10000 and PSW is at #10008). Is this what we should have? Or should we print out the actual PSW and MA?

Sorry about that. Those do look like nonsense values. Feel free to fix any errors like this. The code ought to have output the contents of the saved TMA register (which is irrelevant in the case of this particular trap) and the contents of the saved PSW. Indeed, those look like the addresses of the save locations.

As of about 9PM Sunday Nov. 29, I simplified the trap handler in the Hawk monitor to fix the above error. It no longer outputs the Trap PSW line (since that is restored before the halt), and it conforms a bit better to the current Hawk programming conventions, using LIL R,XXX instead of the ugly LOAD R,XXXP code of the old monitor. If you've already successfully duplicated the old code, that's OK, but if you haven't, the new code should be easier to duplicate.

Needless to say, the grader won't be picky about this. The Trap PC, however, will be checked carefully.

I'm having trouble with right shifts. The problem is, bits being shifted across the gap between words gets garbled. Here's my code:

                SR      R4,1    ; shift least significant word
                SR      R5,1    ; shift most significant word
		ADJUST  R4,CMSB ; put bit from high word into low word

You used SR where you should have used SRU to shift R4. The result was that the high bit of the low word got duplicated with each shift.

This points out an ambiguity in the assignment. Is the new DSR instruction supposed to be a signed shift or an unsigned shift? It never says outright, however, the name itself is a strong hint. The name DSR is analogous to SR, the signed right shift, not to SRU, the unsigned right shift.

What exactly is meant by "double-precision shift"? Are we working with long integers as in MP4? In that case, does the input register contain a memory address for the long integer, or does it directly contain the low or high word, with the other one perhaps held in the directly following register?

You are to shift a 64-bit integer operand composed of 2 32-bit halves. Indeed, you are working with long integers as in MP4. The only machine instructions on the Hawk that take memory addresses as operands are load and store. Shift and arithmetic instructions on the Hawk all operate on operands in registers. So, the natural way to code double-precision shift instructions is to have them also operate on registers, with each operand held in a pair of registers. The reason the instruction format limits the destination register to even registers is that the even register in each pair holds the low word and the odd register holds the high word.

So explicitly selecting an even-numbered register to contain the low-order word would implicitly select the next-higher register to contain the high-order word? If I am right, the legal input registers are the pairs R2-R3, R4-R5, ... , RE-RF. Right?

Exactly.

When I try to use CMPI R5,#8010 to check for the right opcode, it doesn't work. Why?

The 16-bit constant used as an argument to the CMPI instruction is sign extended to 32 bits before comparison. This means that #8010 is the same as #FFFF8010, which is not what you want. You'll have to use LIL to load the constant and then use a register-to-register compare instruction.

When I try to use CMPI R5,#1080 to identify the opcode, it doesn't work. Why?

Remember, the order of the bytes in the instruction register (or actually, in the Hawk documentation) is reversed from the order they are stored in memory. If you fetch the instruction as a halfword from memory using EXTH, what you should be comparing with is #8010, not 1080.