Machine Problem 6, due May 6
Part of
the homework for 22C:60 (CS:2630), Spring 2013
|
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:
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | dst (nz) | 0 0 0 0 | 0 0 0 0 | LIW | dst,const | r[dst] = const |
15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
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
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.
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.