Machine Problem 6, due May 6

Part of the homework for 22C:60 (CS:2630), Spring 2013
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Background: The Hawk has an LIW macro, but this generates two consecutive machine instructions. The Hawk has several undefined instructions that, if used, cause an instruction trap. One of these is the halfword 00F016.

If we wanted to add an LIW machine instruction to the Hawk, we could do so by taking over this illegal instruction and using it for this new instruction. In the Hawk manual, this new instruction might be documented like this:

07060504 03020100 15141312 11100908                           
1 1 1 1 dst (nz) 0 0 0 0 0 0 0 0 LIW dst,const r[dst] = const

15141312 11100908 07060504 03020100
const:15:0
const:31:16

The proposed instruction is 48 bits long, with the instruction halfword followed immediately by the 32-bit constant. Note that this 32-bit constant is two consecutive halfwords, and it need not be word aligned in memory, so it must be fetched as halfwords and then composed into a word. The destination register field of the instruction determines which register the constant goes in.

To make the SMAL assembler support this instruction, we need to write a macro for it. This could be added to the hawk.h file, but during development, we can put the new macro at the start of the source file, right after the use "hawk.h" directive. The code given here is largely cribbed from the hawk.h and uses some of the support macros there to build the new machine instruction:

MACRO LIW =dst,=const
  qONE5REGq #F000,dst,0
  W const
ENDMAC

We could build a new version of the Hawk CPU with hardware support for this instruction, but that is a lot of work. As an alternative, we could write a trap handler for the illegal instruction trap to virtualize this instruction.

The new code could be integrated into the hawk monitor, but that is the kind of thing you don't want to fiddle with. Better, during development, to write it as a separate source file containing just the your trap handler. The skeleton of this file might look like this:

        TITLE   "mp6.a -- by ##your name here##"
;       ##some appropriate comments##
        USE     "hawk.h"
        USE     "monitor.h"

; trap save area record structure
; (all fields are 1 word, so displacements are shown in words)
; trap save area record structure
; (all fields are 1 word, so displacements are shown in words)

myCODE  =  0 <<2  ; pointer to trap-specific routine entry
myPSW   =  1 <<2  ; initial PSW to use for trap service
svPC    =  2 <<2  ; save area for PC
svR1    =  3 <<2  ; save area for registers

. . .       . . .      code cribbed from Chapter 13 of the Hawk manual

svRF    = 17 <<2
svPSW   = 18 <<2  ; save area for PSW
svMA    = 19 <<2  ; save area for trap MA
svSIZE  = 20 <<2  ; size of register-save area


INSTRTRAP =     #20
        COMMON  INSTSAVEAREA,SAVEAREASIZE

LCSAVE  =       .
.       =       INSTRTRAP       ; trap vector entry
        CPUSET  R2,TSV          ; partially save R2
        LIL     R2,INSTSAVEAREA ; get the save area pointer
        STORE   R1,R2,svR1      ; save R1
        LIL     R1,HANDLER
        JUMPS   R1              ; go save my registers
.       =       LCSAVE

HANDLER:        ; enter with: R2 points to the save area and stack
                ; TPC holds the user's PC
                ; TSV holds the user's R2
                ; R1 saved in the save area
        STORE   R3,R2,svR3

        . . .   . . . . . .   code cribbed from Chapter 13 of the Hawk manual

The Assignment

Make it work! Crib the necessary code from the manual to fill out the framework of the trap handler, then fill in the details specific to making this trap handler detect and virtualize the new LIW instruction.

Your solution should be in a source file called mp6.a and should be submitted in the usual way. The solution should not include any other code.

Note that if the illegal instruction is something other than the LIW instruction that we are emulating, the trap handler should do the following:

This is, in fact, a close approximation of what the Hawk monitor's trap handler does.

Notes on Testing

Consider this test program as an example:

        TITLE   "mp6test.a test program for MP6"

        USE     "hawk.h"

        ; this macro replaces the original LIW defined in hawk.h
        MACRO LIW =dst,=const
          qONE5REGq #F000,dst,0
          W const
        ENDMAC

        INT     MAIN
        S       MAIN
MAIN:
        LIW     R1, #1248EDB7
        LIW     R2, #E0000000
        ADD     R3,R1,R2        ; R3  = #F248EDB7
        LIW     R4, #0D000000
        ADD     R5,R3,R4        ; R5  = #FF48EDB7
        LIW     R6, #00B00000
        ADD     R7,R6,R5        ; R7  = #FFF8EDB7
        LIW     R8, #00070000
        ADD     R9,R7,R8        ; R9  = #FFFFEDB7
        LIW     R10,#00001000
        ADD     R11,R9,R10      ; R11 = #FFFFFDB7
        LIW     R12,#00000200
        ADD     R13,R12,R11     ; R13 = #FFFFFFB7
        LIW     R14,#00000040
        LIW     R15,#00000008
        OR      R15,R14         ; R15 = #FFFFFFF7
        OR      R15,R13         ; R15 = #FFFFFFFF
        H       #10F0           ; an illegal instruction

        END

The above program is not useful, but it is designed for single stepping in order to observe the progress of the computation. To assemble and link your solution to MP6 with this test program, do this:

smal mp6.a
smal mp6test.a
link mp6.o mp6test.o

The way the link command works, it first links the monitor into memory, and then links mp6.o and your test file into memory. Because mp6.o is linked after the monitor, your handler for the illegal instruction trap replaces the handler that is part of the monitor. There are no INT and EXT directives to connect your handler to the system, unless you put code in your handler to call monitor routines to generate output (either for debugging or to report errors).

When you run your program, it should terminate with an illegal instruction trap with your trap message (not the slightly different Hawk monitor trap message). Furthermore, because all the registers were restored prior to the error message and halt, you should see all the values in the registers indicated by the comments in the program.

If you run the program using the monitor's s (single step) command, you can follow the progress of the execution through your trap handler.

If you run the program using the monitor's n (execute until next instruction) command, you can see it execute as if the emulated instruction was a built-in instruction.