Homework 6 Solutions

22C:18, Summer 1997

Douglas W. Jones

  1. I/O was not discussed, nor was addressing of any but simple variables. That is, there was no discussion of array addressing, pointers, or other data structures! Character and other non-integer operations were also omitted.

  2. Using the following (bad) idea: The following macros suffice:
    MACRO add
      ADDSI R4,-4
      LOADS R1,R4
      LOAD  R2,R4,-4
      ADD R2,R1,R2
      STORE R2,R4,-4
    ENDMAC
    
    MACRO sub
      ADDSI R4,-4
      LOADS R1,R4
      LOAD  R2,R4,-4
      SUB R2,R2,R1
      STORE R2,R4,-4
    ENDMAC
    
    MACRO pushimm =c
      LIL    R1,c
      STORES R1,R4
      ADDSI  R4,-4
    ENDMAC
    
    MACRO pushlocal var
      LOAD	R1,R3,var
      STORES R1,R4
      ADDSI  R4,-4
    ENDMAC
    
    MACRO bne lab
      ADDSI  R4,-4
      LOADSCC R1,R4
      BNE lab
    ENDMAC
    
    MACRO function name
      name:
    ENDMAC
    
    MACRO funcreturn
      ADDSI  R4,-4
      LOADS  R1,R4	; temp = pop()
      MOVE   R4,R3  ; SP = FP
      ADDSI  R4,-4
      LOADS  R3,R4  ; FP = pop()
      ADDSI  R4,-4
      LOADS  R2,R4	; temp1 = pop()
      STORES R1,R4  ; push(temp)
      ADDSI  R4,4
      JUMPS  R2	; PC = temp1
    ENDMAC
    
    MACRO pushmark
      STORES R0,R4
      ADDSI  R4,4	; push(0)
      STORES R3,R4
      ADDSI  R4,4   ; push(FP)
    ENDMAC
    
    MACRO paramcall func,params
      LIS	 R1,params << 2
      SUB    R3,R4,R1  ; FP = SP - (params << 4)
      LEA    R1,.+8    ; M[FP - (2 << 4)] = returnPC
      JUMP   func      ; PC = func
    		   ; .+8 sets return point to here!
    ENDMAC
    

  3. Here is a more efficient version of pushlocal that uses the proper load immediate instruction depending on the value of its parameter.
    MACRO pushlocal =c
      IF    (c < -128) ! (c > 128)
        IF  (c < -#800000) ! (c > #FFFFFF)
          LIL    R1,const
        ELSE
          LIW    R1,const
        ENDIF
      ELSE
        LIS    R1,const
      ENDIF
      STORES R1,R4
      ADDSI  R4,-4
    ENDMAC
    

  4. Here is a main program to call the procedure written using the above macros.
    START:	LOAD	R2,PSTACK
    	CALL	DSPINI
    
    	; change gears to funny calling sequence
    	MOVE	R4,R2	; switch stack pointer to new register
    	LEA	R1,RA	; push return address
    	STORES	R1,R4
    	ADDSI	R4,4
    	ADDSI	R4,4	; push nothing (we have no frame that matters)
    	MOVE    R3,R4   ; set up frame pointer for function
    	LIS	R1,3	; push a parameter
    	STORES	R1,R4
    	ADDSI	R4,4
    	LIS	R1,4	; push another parameter
    	STORES	R1,R4
    	ADDSI	R4,4
    	JUMP	multiply
    RA:
    	ADDSI	R2,-4
    	LOADS	R3,R2	; pop result into R3
    
    	; change gears back from funny calling sequence
    	MOVE	R2,R4	; switch stack pointer back home
    
    	; output result gears back from funny calling sequence
    	LIS	R4,5
    	CALL	DSPDEC
    
    	; now, do it again, different numbers
    
            ; change gears to funny calling sequence
            MOVE    R4,R2   ; switch stack pointer to new register
            LEA     R1,RA1  ; push return address
            STORES  R1,R4
            ADDSI   R4,4
            ADDSI   R4,4    ; push nothing (we have no frame that matters)
            MOVE    R3,R4   ; set up frame pointer for function
            LIS     R1,4    ; push a parameter      
            STORES  R1,R4
            ADDSI   R4,4
            LIS     R1,5    ; push another parameter
            STORES  R1,R4
            ADDSI   R4,4
            JUMP    multiply
    RA1:
            ADDSI   R2,-4
            LOADS   R3,R2   ; pop result into R3
    
            ; change gears back from funny calling sequence
            MOVE    R2,R4   ; switch stack pointer back home
    
            ; output result gears back from funny calling sequence
            LIS     R4,5
            CALL    DSPDEC
    
    	; quit
    	LIS	R1,0
    	JUMPS	R1