xref: /netbsd/external/bsd/pcc/dist/pcc/arch/nova/README (revision 6550d01e)
1Calling conventions, stack frame and zero page:
2
3The variables that normally are placed on the stack or in registers in C
4are instead allocated in the zero page and saved on a (fictive) stack
5when calling functions.  Some locations have predefined functions though.
6Arrays allocated as automatics are stored on the stack with a pointer
7in zero page to its destination.
8
90-7	Unused
1010	Stack pointer
1111	Frame pointer
1212-14	Unused
1315	Used by prolog
1416	Prolog address, written in crt0
1517	Epilog address, written in crt0
1620-27	Auto-increment, scratch
1730-37	Auto-decrement, scratch
1840-47	Unused
1950-57	Scratch/Arguments
2060-77	Permanent, save before use.
21100-377	Addresses for subroutines, written by the assembler
22
23The normal registers (AC0-AC3) are all considered scratch registers.
24
25Register classes are assigned as:
26	AC0-AC3: AREGs.
27	AC2-AC3: BREGs.
28	50-77:	 CREGs.
29	...and eventually register pairs as DREGs.
30
31In byte code the low half of a word is the first byte (little-endian).
32This is bit 8-15 in Nova syntax.
33
34The stack is growing towards lower adresses (as opposed to the Eclipse stack).
35Stack layout:
36
37	! arg1	!
38	! arg0	!
39 fp ->	! old pc!
40	! old fp!
41 pc ->	! saved !
42
43A reference to a struct member in assembler, a = b->c; b is in ZP 50
44+ is zeropage-addressing
45* is fp-adressing
46
47# offset 0
48+	lda 0,@50	# load value from indirect ZP 50 into ac0
49*	lda 2,,3	# load value from (ac3) into ac2
50*	lda 0,,2	# load value from (ac2) into ac0
51
52# offset 12
53+	lda 2,50	# load value from ZP 50 into ac2
54+	lda 0,12,2	# load value from (ac2+12) into ac0
55*	lda 2,,3	# load value from (ac3) into ac2
56*	lda 0,12,2	# load value from 12(ac2) into ac0
57
58# offset 517
59+	lda 2,50	# load value from ZP 50 into ac2
60+	lda 0,.L42-.,1	# load offset from .L42 PC-indexed
61+	addz 0,2,skp	# add offset to ac2 and skip
62+.L42:	.word 517	# offset value
63+	lda 0,,2	# load value from (ac2) into ac0
64
65The prolog/epilog implementation; it is implemented as subroutines.
66
67.L42:	.word 13	# number of words to save
68func:
69	sta 3,@40	# save return address on stack
70	lda 2,.L42-.,1	# get save word count
71	jsr @45		# go to prolog
72	...
73	lda 2,.L42-.,1	# get restore word count
74	jmp @46		# jump to epilog
75
76# words to save in 2, return address in 3
77prolog:
78	sta 2,45	# save # of words to move at scratch
79	lda 0,41	# get old fp
80	lda 1,40	# get sp
81	sta 1,41	# save new fp
82	dsz 40		# decrement stack, will never be 0
83	sta 0,@40	# save old fp
84	dsz 40
85
86	lda 0,off57	# fetch address of regs to save - 1
87	sta 0,20	# store address at autoincr
881:	lda 0,@20	# get word to copy
89	sta 0,@40	# push on stack
90	dsz 40		# manually decrement sp
91	dsz 45		# copied all words?
92	jmp 1b,1	# no, continue
93	jmp 0,3		# return
94
95epilog:
96	sta 2,45	# save # of words to move at scratch
97
98	lda 3,off57	# fetch address of regs to save
99	sta 3,20	# store at autoincr
100	lda 3,41	# fetch fp
101	sta 3,30	# store at autodecr
102	lda 3,@30	# get old fp
103
1041:	lda 2,@30	# fetch word from stack
105	sta 2,@20	# store at orig place
106	dsz 45		# enough?
107	jmp 1b,1	# no, continue
108
109	lda 2,41	# get new fp
110	sta 2,40	# restore stack
111	sta 3,41	# restore old fp
112	jmp @40		# Return
113
114Assembler syntax and functions.
115
116The assembler syntax mimics the DG assembler.
117Load and store to addresses is written "lda 0,foo" to load from address foo.
118If foo is not in zero page then the assembler will put the lda in the
119text area close to the instruction and do an indirect pc-relative load.
120
121