chiark / gitweb /
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