-
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.
-
Using the following (bad) idea:
- Set aside R1-2 as short-term temporaries
- Set asider R3 as the frame pointer
- Set aside R4 as the stack pointer
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
-
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
-
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