Initial revision
[ssr] / StraySrc / Libraries / BAS / src / s / lit
1 ;
2 ; lit.s
3 ;
4 ; Literal pool management
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's BASIC Assembler Supplement.
12 ;
13 ; BAS is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; BAS is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with BAS. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 GET libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36 GET sh.aofGen
37 GET sh.bas
38 GET sh.fastMove
39 GET sh.flex
40 GET sh.insert
41 GET sh.workspace
42
43 ;----- Main code ------------------------------------------------------------
44
45 AREA |BAS$$Code|,CODE,READONLY
46
47 ; --- lit_add ---
48 ;
49 ; On entry: R0 == address of literal data
50 ; R1 == size of literal data
51 ; R2 == word align flag
52 ;
53 ; On exit: R0 set up as described below.
54 ;
55 ; Use: Adds the given data to the current literal pool. On the
56 ; first pass, it returns the value of P% in R0. On the
57 ; second pass, it returns the address of the literal item.
58
59 EXPORT lit_add
60 lit_add ROUT
61
62 STMFD R13!,{R1-R5,R12,R14} ;Save some registers
63 STR R12,[R7,#:INDEX:be__line] ;Store line value
64 MOV R12,R7 ;Find my workspace
65 MOV R3,R0 ;Keep the start address
66 MOV R4,R1 ;And the size of the block
67
68 BL aof_firstPass ;Is this the first pass?
69 BCS %50lit_add ;Yes -- behave totally oddly
70
71 ; --- Handle word aligning ---
72
73 CMP R2,#0 ;Is the word align flag on?
74 BEQ %10lit_add ;No -- don't bother then
75 LDR R1,lit__contents+4 ;Load the current size
76 ANDS R1,R1,#3 ;Get the nonwordalignedness
77 BEQ %10lit_add ;No excess -- skip on then
78 RSB R1,R1,#4 ;Find how much we have to add
79 ADR R0,lit__contents ;Point to the contents block
80 BL aof_ensure ;Get the memory area
81 MOV R14,#0 ;A nice zero byte
82 05lit_add STRB R14,[R0],#1 ;Store it in the block
83 SUBS R1,R1,#1 ;Decrement the counter
84 BGT %05lit_add ;And carry on round
85
86 ; --- Now add the contents ---
87
88 10lit_add LDR R5,lit__contents+4 ;Load offset of literal item
89 ADR R0,lit__contents ;Point to the contents block
90 MOV R1,R4 ;Get the block size
91 BL aof_ensure ;Make sure it's big enough
92 MOV R1,R3 ;Point to caller's block
93 MOV R2,R4 ;Get the size
94 BL fastMove ;Copy it over PDQ
95
96 ; --- Now return the correct address ---
97
98 LDR R14,lit__next ;Find next literal index
99 LDR R0,lit__table ;Find the literal table
100 LDR R0,[R0,R14] ;Load the pool base address
101 ADD R0,R0,R5 ;And add the item offset
102 LDMFD R13!,{R1-R5,R12,PC}^ ;And return to caller
103
104 ; --- Handle a literal pool request on first pass ---
105
106 50lit_add LDR R3,lit__contents+4 ;Load the current size
107 CMP R2,#0 ;Are we word aligning?
108 ADDNE R3,R3,#3 ;If so, word align this
109 BICNE R3,R3,#3 ;In time-honoured fashion
110 ADD R3,R3,R1 ;Add on size of item
111 STR R3,lit__contents+4 ;Save the new size back
112 LDR R0,be__percents ;Find the % variables
113 LDR R0,[R0,#('P'-'A')*4] ;Load current P% value
114 LDMFD R13!,{R1-R5,R12,PC}^ ;And return to caller
115
116 LTORG
117
118 ; --- lit_ltorg ---
119 ;
120 ; On entry: --
121 ;
122 ; On exit: --
123 ;
124 ; Use: Inserts a literal pool at the current position.
125
126 EXPORT lit_ltorg
127 lit_ltorg ROUT
128
129 STMFD R13!,{R0-R4,R12,R14} ;Save some registers
130 STR R12,[R7,#:INDEX:be__line] ;Store line value
131 MOV R12,R7 ;Find my workspace
132 BL insert_align ;Word align current pos
133
134 LDR R14,lit__contents+4 ;Any data in literal pool?
135 CMP R14,#0 ;If so, this won't be 0
136 BEQ %90lit_ltorg ;No -- just align then
137
138 LDR R4,be__percents ;Find the % variables
139
140 BL aof_firstPass ;Is this the first pass?
141 BCC %20lit_ltorg ;No -- do the copying then
142
143 ; --- Add an entry into the literal table ---
144
145 LDR R2,[R4,#('P'-'A')*4] ;Load current P% value
146 ADR R0,lit__table ;Find the literal table
147 MOV R1,#4 ;Entries are 1 word long
148 BL aof_ensure ;Make the space for it
149 STR R2,[R0],#4 ;Store address in the block
150 B %50lit_ltorg ;Do the rest of the LTORG op
151
152 ; --- Copy the data in the pool over ---
153
154 20lit_ltorg LDR R0,[R4,#('O'-'A')*4] ;Load current O% value
155 ADR R1,lit__contents ;Find the pool contents
156 LDMIA R1,{R1,R2} ;Load address and size
157 BL fastMove ;Copy the data over
158
159 ADR R0,lit__contents ;Point to the anchor
160 MOV R1,#256 ;Reduce it in size again
161 BL flex_extend ;Put the block back again
162 STR R1,lit__contents+8 ;Save this as the block size
163
164 LDR R14,lit__next ;Load next literal pool index
165 ADD R14,R14,#4 ;Bump it along one word
166 STR R14,lit__next ;Save it back again
167
168 ; --- Now move on P% and O% ---
169
170 50lit_ltorg LDR R0,lit__contents+4 ;Load the pool size
171 ADD R1,R4,#('O'-'A')*4 ;Point to current O% value
172 LDMIA R1,{R2,R3} ;Load O% and P% out
173 ADD R2,R2,R0 ;Bump O% along
174 ADD R3,R3,R0 ;Bump P% along
175 STMIA R1,{R2,R3} ;Save adjusted values back
176
177 MOV R0,#0 ;Next literal pool is clear
178 STR R0,lit__contents+4 ;So reset its size to 0
179
180 90lit_ltorg BL insert_align ;Word align location
181
182 LDMFD R13!,{R0-R4,R12,PC}^ ;And return to caller
183
184 LTORG
185
186 ; --- lit_init ---
187 ;
188 ; On entry: --
189 ;
190 ; On exit: --
191 ;
192 ; Use: Initialises things for the Literal Manager.
193
194 EXPORT lit_init
195 lit_init ROUT
196
197 STMFD R13!,{R0-R3,R14} ;Save some registers
198 MOV R2,#0 ;Blocks currently empty
199 MOV R3,#256 ;Initial size is 256
200 MOV R1,#256 ;Allocate to 256 bytes
201
202 ADR R0,lit__table ;Point to lit table anchor
203 BL flex_alloc ;Try to allocate memory
204 STMCCIB R0,{R2,R3} ;Save size information
205 ADRCC R0,lit__contents ;Point to lit contents anchor
206 BLCC flex_alloc ;Try to allocate memory
207 STMCCIB R0,{R2,R3} ;Save size information
208 BCS bas_noMem ;If no memory, die horridly
209
210 MOV R14,#0 ;No current lit pool index
211 STR R14,lit__next ;So save 0 as index
212 LDMFD R13!,{R0-R3,PC}^ ;And return to caller
213
214 LTORG
215
216 ; --- lit_end ---
217 ;
218 ; On entry: --
219 ;
220 ; On exit: --
221 ;
222 ; Use: Tidies up the Literal Manager after saving an AOF file.
223
224 EXPORT lit_end
225 lit_end ROUT
226
227 STMFD R13!,{R0,R7,R14} ;Save some registers
228 MOV R7,R12 ;For technical reasons
229 LDR R12,be__line ;Keep the line number right
230 BL lit_ltorg ;Insert final literal pool
231 MOV R12,R7 ;Restore the workspace ptr
232 ADR R0,lit__table ;Point to table anchor
233 BL flex_free ;Free the memory
234 ADR R0,lit__contents ;Point to contents block
235 BL flex_free ;Free the memory
236 LDMFD R13!,{R0,R7,PC}^ ;And return to caller
237
238 LTORG
239
240 ;----- That's all, folks ----------------------------------------------------
241
242 END