media/libvpx/vp8/common/arm/neon/sixtappredict4x4_neon.asm

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 ;
michael@0 2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0 3 ;
michael@0 4 ; Use of this source code is governed by a BSD-style license
michael@0 5 ; that can be found in the LICENSE file in the root of the source
michael@0 6 ; tree. An additional intellectual property rights grant can be found
michael@0 7 ; in the file PATENTS. All contributing project authors may
michael@0 8 ; be found in the AUTHORS file in the root of the source tree.
michael@0 9 ;
michael@0 10
michael@0 11
michael@0 12 EXPORT |vp8_sixtap_predict4x4_neon|
michael@0 13 ARM
michael@0 14 REQUIRE8
michael@0 15 PRESERVE8
michael@0 16
michael@0 17 AREA ||.text||, CODE, READONLY, ALIGN=2
michael@0 18
michael@0 19 filter4_coeff
michael@0 20 DCD 0, 0, 128, 0, 0, 0, 0, 0
michael@0 21 DCD 0, -6, 123, 12, -1, 0, 0, 0
michael@0 22 DCD 2, -11, 108, 36, -8, 1, 0, 0
michael@0 23 DCD 0, -9, 93, 50, -6, 0, 0, 0
michael@0 24 DCD 3, -16, 77, 77, -16, 3, 0, 0
michael@0 25 DCD 0, -6, 50, 93, -9, 0, 0, 0
michael@0 26 DCD 1, -8, 36, 108, -11, 2, 0, 0
michael@0 27 DCD 0, -1, 12, 123, -6, 0, 0, 0
michael@0 28
michael@0 29 ; r0 unsigned char *src_ptr,
michael@0 30 ; r1 int src_pixels_per_line,
michael@0 31 ; r2 int xoffset,
michael@0 32 ; r3 int yoffset,
michael@0 33 ; stack(r4) unsigned char *dst_ptr,
michael@0 34 ; stack(lr) int dst_pitch
michael@0 35
michael@0 36 |vp8_sixtap_predict4x4_neon| PROC
michael@0 37 push {r4, lr}
michael@0 38
michael@0 39 adr r12, filter4_coeff
michael@0 40 ldr r4, [sp, #8] ;load parameters from stack
michael@0 41 ldr lr, [sp, #12] ;load parameters from stack
michael@0 42
michael@0 43 cmp r2, #0 ;skip first_pass filter if xoffset=0
michael@0 44 beq secondpass_filter4x4_only
michael@0 45
michael@0 46 add r2, r12, r2, lsl #5 ;calculate filter location
michael@0 47
michael@0 48 cmp r3, #0 ;skip second_pass filter if yoffset=0
michael@0 49 vld1.s32 {q14, q15}, [r2] ;load first_pass filter
michael@0 50
michael@0 51 beq firstpass_filter4x4_only
michael@0 52
michael@0 53 vabs.s32 q12, q14 ;get abs(filer_parameters)
michael@0 54 vabs.s32 q13, q15
michael@0 55
michael@0 56 sub r0, r0, #2 ;go back 2 columns of src data
michael@0 57 sub r0, r0, r1, lsl #1 ;go back 2 lines of src data
michael@0 58
michael@0 59 ;First pass: output_height lines x output_width columns (9x4)
michael@0 60 vld1.u8 {q3}, [r0], r1 ;load first 4-line src data
michael@0 61 vdup.8 d0, d24[0] ;first_pass filter (d0-d5)
michael@0 62 vld1.u8 {q4}, [r0], r1
michael@0 63 vdup.8 d1, d24[4]
michael@0 64 vld1.u8 {q5}, [r0], r1
michael@0 65 vdup.8 d2, d25[0]
michael@0 66 vld1.u8 {q6}, [r0], r1
michael@0 67 vdup.8 d3, d25[4]
michael@0 68 vdup.8 d4, d26[0]
michael@0 69 vdup.8 d5, d26[4]
michael@0 70
michael@0 71 pld [r0]
michael@0 72 pld [r0, r1]
michael@0 73 pld [r0, r1, lsl #1]
michael@0 74
michael@0 75 vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
michael@0 76 vext.8 d19, d8, d9, #5
michael@0 77 vext.8 d20, d10, d11, #5
michael@0 78 vext.8 d21, d12, d13, #5
michael@0 79
michael@0 80 vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
michael@0 81 vswp d11, d12
michael@0 82
michael@0 83 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
michael@0 84 vzip.32 d20, d21
michael@0 85 vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 86 vmull.u8 q8, d20, d5
michael@0 87
michael@0 88 vmov q4, q3 ;keep original src data in q4 q6
michael@0 89 vmov q6, q5
michael@0 90
michael@0 91 vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
michael@0 92 vzip.32 d10, d11
michael@0 93 vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
michael@0 94 vshr.u64 q10, q6, #8
michael@0 95 vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
michael@0 96 vmlal.u8 q8, d10, d0
michael@0 97
michael@0 98 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
michael@0 99 vzip.32 d20, d21
michael@0 100 vshr.u64 q3, q4, #32 ;construct src_ptr[2]
michael@0 101 vshr.u64 q5, q6, #32
michael@0 102 vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 103 vmlsl.u8 q8, d20, d1
michael@0 104
michael@0 105 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
michael@0 106 vzip.32 d10, d11
michael@0 107 vshr.u64 q9, q4, #16 ;construct src_ptr[0]
michael@0 108 vshr.u64 q10, q6, #16
michael@0 109 vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 110 vmlsl.u8 q8, d10, d4
michael@0 111
michael@0 112 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
michael@0 113 vzip.32 d20, d21
michael@0 114 vshr.u64 q3, q4, #24 ;construct src_ptr[1]
michael@0 115 vshr.u64 q5, q6, #24
michael@0 116 vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 117 vmlal.u8 q8, d20, d2
michael@0 118
michael@0 119 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
michael@0 120 vzip.32 d10, d11
michael@0 121 vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 122 vmull.u8 q10, d10, d3
michael@0 123
michael@0 124 vld1.u8 {q3}, [r0], r1 ;load rest 5-line src data
michael@0 125 vld1.u8 {q4}, [r0], r1
michael@0 126
michael@0 127 vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
michael@0 128 vqadd.s16 q8, q10
michael@0 129
michael@0 130 vld1.u8 {q5}, [r0], r1
michael@0 131 vld1.u8 {q6}, [r0], r1
michael@0 132
michael@0 133 vqrshrun.s16 d27, q7, #7 ;shift/round/saturate to u8
michael@0 134 vqrshrun.s16 d28, q8, #7
michael@0 135
michael@0 136 ;First Pass on rest 5-line data
michael@0 137 vld1.u8 {q11}, [r0], r1
michael@0 138
michael@0 139 vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
michael@0 140 vext.8 d19, d8, d9, #5
michael@0 141 vext.8 d20, d10, d11, #5
michael@0 142 vext.8 d21, d12, d13, #5
michael@0 143
michael@0 144 vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
michael@0 145 vswp d11, d12
michael@0 146
michael@0 147 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
michael@0 148 vzip.32 d20, d21
michael@0 149 vext.8 d31, d22, d23, #5 ;construct src_ptr[3]
michael@0 150 vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 151 vmull.u8 q8, d20, d5
michael@0 152 vmull.u8 q12, d31, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 153
michael@0 154 vmov q4, q3 ;keep original src data in q4 q6
michael@0 155 vmov q6, q5
michael@0 156
michael@0 157 vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
michael@0 158 vzip.32 d10, d11
michael@0 159 vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
michael@0 160 vshr.u64 q10, q6, #8
michael@0 161
michael@0 162 vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
michael@0 163 vmlal.u8 q8, d10, d0
michael@0 164 vmlal.u8 q12, d22, d0 ;(src_ptr[-2] * vp8_filter[0])
michael@0 165
michael@0 166 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
michael@0 167 vzip.32 d20, d21
michael@0 168 vshr.u64 q3, q4, #32 ;construct src_ptr[2]
michael@0 169 vshr.u64 q5, q6, #32
michael@0 170 vext.8 d31, d22, d23, #1 ;construct src_ptr[-1]
michael@0 171
michael@0 172 vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 173 vmlsl.u8 q8, d20, d1
michael@0 174 vmlsl.u8 q12, d31, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 175
michael@0 176 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
michael@0 177 vzip.32 d10, d11
michael@0 178 vshr.u64 q9, q4, #16 ;construct src_ptr[0]
michael@0 179 vshr.u64 q10, q6, #16
michael@0 180 vext.8 d31, d22, d23, #4 ;construct src_ptr[2]
michael@0 181
michael@0 182 vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 183 vmlsl.u8 q8, d10, d4
michael@0 184 vmlsl.u8 q12, d31, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 185
michael@0 186 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
michael@0 187 vzip.32 d20, d21
michael@0 188 vshr.u64 q3, q4, #24 ;construct src_ptr[1]
michael@0 189 vshr.u64 q5, q6, #24
michael@0 190 vext.8 d31, d22, d23, #2 ;construct src_ptr[0]
michael@0 191
michael@0 192 vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 193 vmlal.u8 q8, d20, d2
michael@0 194 vmlal.u8 q12, d31, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 195
michael@0 196 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
michael@0 197 vzip.32 d10, d11
michael@0 198 vext.8 d31, d22, d23, #3 ;construct src_ptr[1]
michael@0 199 vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 200 vmull.u8 q10, d10, d3
michael@0 201 vmull.u8 q11, d31, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 202
michael@0 203 add r3, r12, r3, lsl #5
michael@0 204
michael@0 205 vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
michael@0 206 vqadd.s16 q8, q10
michael@0 207 vqadd.s16 q12, q11
michael@0 208
michael@0 209 vext.8 d23, d27, d28, #4
michael@0 210 vld1.s32 {q5, q6}, [r3] ;load second_pass filter
michael@0 211
michael@0 212 vqrshrun.s16 d29, q7, #7 ;shift/round/saturate to u8
michael@0 213 vqrshrun.s16 d30, q8, #7
michael@0 214 vqrshrun.s16 d31, q12, #7
michael@0 215
michael@0 216 ;Second pass: 4x4
michael@0 217 vabs.s32 q7, q5
michael@0 218 vabs.s32 q8, q6
michael@0 219
michael@0 220 vext.8 d24, d28, d29, #4
michael@0 221 vext.8 d25, d29, d30, #4
michael@0 222 vext.8 d26, d30, d31, #4
michael@0 223
michael@0 224 vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5)
michael@0 225 vdup.8 d1, d14[4]
michael@0 226 vdup.8 d2, d15[0]
michael@0 227 vdup.8 d3, d15[4]
michael@0 228 vdup.8 d4, d16[0]
michael@0 229 vdup.8 d5, d16[4]
michael@0 230
michael@0 231 vmull.u8 q3, d27, d0 ;(src_ptr[-2] * vp8_filter[0])
michael@0 232 vmull.u8 q4, d28, d0
michael@0 233
michael@0 234 vmull.u8 q5, d25, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 235 vmull.u8 q6, d26, d5
michael@0 236
michael@0 237 vmlsl.u8 q3, d29, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 238 vmlsl.u8 q4, d30, d4
michael@0 239
michael@0 240 vmlsl.u8 q5, d23, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 241 vmlsl.u8 q6, d24, d1
michael@0 242
michael@0 243 vmlal.u8 q3, d28, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 244 vmlal.u8 q4, d29, d2
michael@0 245
michael@0 246 vmlal.u8 q5, d24, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 247 vmlal.u8 q6, d25, d3
michael@0 248
michael@0 249 add r0, r4, lr
michael@0 250 add r1, r0, lr
michael@0 251 add r2, r1, lr
michael@0 252
michael@0 253 vqadd.s16 q5, q3 ;sum of all (src_data*filter_parameters)
michael@0 254 vqadd.s16 q6, q4
michael@0 255
michael@0 256 vqrshrun.s16 d3, q5, #7 ;shift/round/saturate to u8
michael@0 257 vqrshrun.s16 d4, q6, #7
michael@0 258
michael@0 259 vst1.32 {d3[0]}, [r4] ;store result
michael@0 260 vst1.32 {d3[1]}, [r0]
michael@0 261 vst1.32 {d4[0]}, [r1]
michael@0 262 vst1.32 {d4[1]}, [r2]
michael@0 263
michael@0 264 pop {r4, pc}
michael@0 265
michael@0 266
michael@0 267 ;---------------------
michael@0 268 firstpass_filter4x4_only
michael@0 269 vabs.s32 q12, q14 ;get abs(filer_parameters)
michael@0 270 vabs.s32 q13, q15
michael@0 271
michael@0 272 sub r0, r0, #2 ;go back 2 columns of src data
michael@0 273
michael@0 274 ;First pass: output_height lines x output_width columns (4x4)
michael@0 275 vld1.u8 {q3}, [r0], r1 ;load first 4-line src data
michael@0 276 vdup.8 d0, d24[0] ;first_pass filter (d0-d5)
michael@0 277 vld1.u8 {q4}, [r0], r1
michael@0 278 vdup.8 d1, d24[4]
michael@0 279 vld1.u8 {q5}, [r0], r1
michael@0 280 vdup.8 d2, d25[0]
michael@0 281 vld1.u8 {q6}, [r0], r1
michael@0 282
michael@0 283 vdup.8 d3, d25[4]
michael@0 284 vdup.8 d4, d26[0]
michael@0 285 vdup.8 d5, d26[4]
michael@0 286
michael@0 287 vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
michael@0 288 vext.8 d19, d8, d9, #5
michael@0 289 vext.8 d20, d10, d11, #5
michael@0 290 vext.8 d21, d12, d13, #5
michael@0 291
michael@0 292 vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
michael@0 293 vswp d11, d12
michael@0 294
michael@0 295 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
michael@0 296 vzip.32 d20, d21
michael@0 297 vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 298 vmull.u8 q8, d20, d5
michael@0 299
michael@0 300 vmov q4, q3 ;keep original src data in q4 q6
michael@0 301 vmov q6, q5
michael@0 302
michael@0 303 vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
michael@0 304 vzip.32 d10, d11
michael@0 305 vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
michael@0 306 vshr.u64 q10, q6, #8
michael@0 307 vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
michael@0 308 vmlal.u8 q8, d10, d0
michael@0 309
michael@0 310 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
michael@0 311 vzip.32 d20, d21
michael@0 312 vshr.u64 q3, q4, #32 ;construct src_ptr[2]
michael@0 313 vshr.u64 q5, q6, #32
michael@0 314 vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 315 vmlsl.u8 q8, d20, d1
michael@0 316
michael@0 317 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
michael@0 318 vzip.32 d10, d11
michael@0 319 vshr.u64 q9, q4, #16 ;construct src_ptr[0]
michael@0 320 vshr.u64 q10, q6, #16
michael@0 321 vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 322 vmlsl.u8 q8, d10, d4
michael@0 323
michael@0 324 vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
michael@0 325 vzip.32 d20, d21
michael@0 326 vshr.u64 q3, q4, #24 ;construct src_ptr[1]
michael@0 327 vshr.u64 q5, q6, #24
michael@0 328 vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 329 vmlal.u8 q8, d20, d2
michael@0 330
michael@0 331 vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
michael@0 332 vzip.32 d10, d11
michael@0 333 vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 334 vmull.u8 q10, d10, d3
michael@0 335
michael@0 336 add r0, r4, lr
michael@0 337 add r1, r0, lr
michael@0 338 add r2, r1, lr
michael@0 339
michael@0 340 vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
michael@0 341 vqadd.s16 q8, q10
michael@0 342
michael@0 343 vqrshrun.s16 d27, q7, #7 ;shift/round/saturate to u8
michael@0 344 vqrshrun.s16 d28, q8, #7
michael@0 345
michael@0 346 vst1.32 {d27[0]}, [r4] ;store result
michael@0 347 vst1.32 {d27[1]}, [r0]
michael@0 348 vst1.32 {d28[0]}, [r1]
michael@0 349 vst1.32 {d28[1]}, [r2]
michael@0 350
michael@0 351 pop {r4, pc}
michael@0 352
michael@0 353
michael@0 354 ;---------------------
michael@0 355 secondpass_filter4x4_only
michael@0 356 sub r0, r0, r1, lsl #1
michael@0 357 add r3, r12, r3, lsl #5
michael@0 358
michael@0 359 vld1.32 {d27[0]}, [r0], r1 ;load src data
michael@0 360 vld1.s32 {q5, q6}, [r3] ;load second_pass filter
michael@0 361 vld1.32 {d27[1]}, [r0], r1
michael@0 362 vabs.s32 q7, q5
michael@0 363 vld1.32 {d28[0]}, [r0], r1
michael@0 364 vabs.s32 q8, q6
michael@0 365 vld1.32 {d28[1]}, [r0], r1
michael@0 366 vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5)
michael@0 367 vld1.32 {d29[0]}, [r0], r1
michael@0 368 vdup.8 d1, d14[4]
michael@0 369 vld1.32 {d29[1]}, [r0], r1
michael@0 370 vdup.8 d2, d15[0]
michael@0 371 vld1.32 {d30[0]}, [r0], r1
michael@0 372 vdup.8 d3, d15[4]
michael@0 373 vld1.32 {d30[1]}, [r0], r1
michael@0 374 vdup.8 d4, d16[0]
michael@0 375 vld1.32 {d31[0]}, [r0], r1
michael@0 376 vdup.8 d5, d16[4]
michael@0 377
michael@0 378 vext.8 d23, d27, d28, #4
michael@0 379 vext.8 d24, d28, d29, #4
michael@0 380 vext.8 d25, d29, d30, #4
michael@0 381 vext.8 d26, d30, d31, #4
michael@0 382
michael@0 383 vmull.u8 q3, d27, d0 ;(src_ptr[-2] * vp8_filter[0])
michael@0 384 vmull.u8 q4, d28, d0
michael@0 385
michael@0 386 vmull.u8 q5, d25, d5 ;(src_ptr[3] * vp8_filter[5])
michael@0 387 vmull.u8 q6, d26, d5
michael@0 388
michael@0 389 vmlsl.u8 q3, d29, d4 ;-(src_ptr[2] * vp8_filter[4])
michael@0 390 vmlsl.u8 q4, d30, d4
michael@0 391
michael@0 392 vmlsl.u8 q5, d23, d1 ;-(src_ptr[-1] * vp8_filter[1])
michael@0 393 vmlsl.u8 q6, d24, d1
michael@0 394
michael@0 395 vmlal.u8 q3, d28, d2 ;(src_ptr[0] * vp8_filter[2])
michael@0 396 vmlal.u8 q4, d29, d2
michael@0 397
michael@0 398 vmlal.u8 q5, d24, d3 ;(src_ptr[1] * vp8_filter[3])
michael@0 399 vmlal.u8 q6, d25, d3
michael@0 400
michael@0 401 add r0, r4, lr
michael@0 402 add r1, r0, lr
michael@0 403 add r2, r1, lr
michael@0 404
michael@0 405 vqadd.s16 q5, q3 ;sum of all (src_data*filter_parameters)
michael@0 406 vqadd.s16 q6, q4
michael@0 407
michael@0 408 vqrshrun.s16 d3, q5, #7 ;shift/round/saturate to u8
michael@0 409 vqrshrun.s16 d4, q6, #7
michael@0 410
michael@0 411 vst1.32 {d3[0]}, [r4] ;store result
michael@0 412 vst1.32 {d3[1]}, [r0]
michael@0 413 vst1.32 {d4[0]}, [r1]
michael@0 414 vst1.32 {d4[1]}, [r2]
michael@0 415
michael@0 416 pop {r4, pc}
michael@0 417
michael@0 418 ENDP
michael@0 419
michael@0 420 ;-----------------
michael@0 421
michael@0 422 END

mercurial