Homework 7 Solved

22C:18, Summer 1997

Douglas W. Jones

  1. Convert each of the following to a string of calls to the RPN macros:
    	a = b - (c << 2);
    		pushaddr a
    		pushvar b
    		pushvar c
    		pushimm 2
    		ls
    		sub
    		put
    
    	b = a[ i ];  -- assume i is an array of integers
    		pushaddr b
    		pushaddr a
    		pushvar i
    		pushimm 2
    		ls
    		add
    		get
    		put
    
    	a[ i ] = i + 5;  -- assume i is an array of integers
    		pushaddr a
    		pushvar i
    		pushimm 2
    		ls
    		add
    		pushvar i
    		pushimm 5
    		add
    		put
    
  2. The ars macro turns out to be a real challenge. The built in ARS instruction in the Hawk machine requires a constant shift count, between 1 and 16, but we need a variable. Here's a solution:
    	MACRO ars
    	  qSPq = qSPq - 1
    	  LIS R1,31
    	  AND qSPq,R1	; make sure we don't shift more than 31 places
    	  LS qSPq,1	; multiply shift count by 2
    	  LEA R1,.+8+62
    	  SUB R1,R1,qSPq
    	  JUMPS R1	; jump to the correct shift instruction
    	; .+8 gets here
    	  ARS qSPq-1,1
    	  ARS qSPq-1,1
    	  ARS qSPq-1,1
                .
                .		; 31 shift instructions in a row
                .
    	  ARS qSPq-1,1
    	  ARS qSPq-1,1
    	  ARS qSPq-1,1
    	; .+8+62 gets here
    	ENDMAC
    
    Other workable solutions involve a loop or a full-blown select/case structure

  3. Here is code for the if, else and endif macros: MACRO if qBLOCKNUMq = qBLOCKNUMq + 1 PUSH qBLOCKNUMq qSPq = qSPq - 1 MOVECC R0,qSPq LABGEN (BZS E),qQBLOCKNUMq,() ENDMAC MACRO else TOP qTEMPq LABGEN (JUMP Q),qTEMPq,() LABGEN (E),qTEMPq,(:) ENDMAC MACRO endif POP qTEMPq LABGEN (Q),qTEMPq,(:) ENDMAC

  4. Show the Hawk machine code resulting from the macro expansion:
    	pushvar i
    	      LOAD R3,R2,i	; assume i is local
    	select
    	      CMPI R3,1
    	      BGT TO1
    	      CMPI R3,0
    	      BLT TO1
    	      LEA R1,T1
    	      ADDSL R3,R1,2
    	      LOADS R1,R3
    	      JUMPS R1
    	      TO1:
    	      JUMP O1
    	  case 0
    	      qTEMPq = .
    	      . = T1 + (0 << 2)
    	      W qTEMPq	; make a table entry
    	      . = qTEMPq
    	    xxxx
    	    break
    	      JUMP Q1
    	  case 1
    	      qTEMPq = .
    	      . = T1 + (1 << 2)
    	      W qTEMPq	; make a table entry
    	      . = qTEMPq
                yyyy
    	    break
    	      JUMP Q1
    	  otherwise
    	      O1:
    	    zzzz
    	    break
    	      JUMP Q1
            endselect
    	      ALIGN 4
    	      T1:	; this is where the table entries end up
    	      . = . + (((1 - 0) + 1) << 2)
    	      O1:
    	      Q1:
    	

  5. The select/case macros defined here require a break before the end select! Falling into the end select from above will likely cause some kind of trap because you'll end up trying to execute the jump table!