4 ; Literal pool management
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's BASIC Assembler Supplement.
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)
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.
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.
27 ;----- Standard header ------------------------------------------------------
34 ;----- External dependencies ------------------------------------------------
43 ;----- Main code ------------------------------------------------------------
45 AREA |BAS$$Code|,CODE,READONLY
49 ; On entry: R0 == address of literal data
50 ; R1 == size of literal data
51 ; R2 == word align flag
53 ; On exit: R0 set up as described below.
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.
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
68 BL aof_firstPass ;Is this the first pass?
69 BCS %50lit_add ;Yes -- behave totally oddly
71 ; --- Handle word aligning ---
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
86 ; --- Now add the contents ---
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
96 ; --- Now return the correct address ---
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
104 ; --- Handle a literal pool request on first pass ---
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
124 ; Use: Inserts a literal pool at the current position.
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
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
138 LDR R4,be__percents ;Find the % variables
140 BL aof_firstPass ;Is this the first pass?
141 BCC %20lit_ltorg ;No -- do the copying then
143 ; --- Add an entry into the literal table ---
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
152 ; --- Copy the data in the pool over ---
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
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
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
168 ; --- Now move on P% and O% ---
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
177 MOV R0,#0 ;Next literal pool is clear
178 STR R0,lit__contents+4 ;So reset its size to 0
180 90lit_ltorg BL insert_align ;Word align location
182 LDMFD R13!,{R0-R4,R12,PC}^ ;And return to caller
192 ; Use: Initialises things for the Literal Manager.
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
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
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
222 ; Use: Tidies up the Literal Manager after saving an AOF file.
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
240 ;----- That's all, folks ----------------------------------------------------