1/* 2Copyright (c) 2014, Intel Corporation 3All rights reserved. 4 5Redistribution and use in source and binary forms, with or without 6modification, are permitted provided that the following conditions are met: 7 8 * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 11 * Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 15 * Neither the name of Intel Corporation nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29*/ 30 31/******************************************************************************/ 32// ALGORITHM DESCRIPTION 33// --------------------- 34// 35// Let x=2^k * mx, mx in [1,2) 36// 37// Get B~1/mx based on the output of rcpps instruction (B0) 38// B = int((B0*2^7+0.5))/2^7 39// 40// Reduced argument: r=B*mx-1.0 (computed accurately in high and low parts) 41// 42// Result: k*log(2) - log(B) + p(r) 43// p(r) is a degree 7 polynomial 44// -log(B) read from data table (high, low parts) 45// Result is formed from high and low parts 46// 47// Special cases: 48// log1p(NaN) = quiet NaN, and raise invalid exception 49// log1p(+INF) = that INF 50// log1p(x) = NaN if x < -1 or x = -INF, and raises invalid exception 51// log1p(-1) = -INF, and raises divide-by-zero exception 52// log1p(+/-0) = +/-0 53// 54/******************************************************************************/ 55 56#include <private/bionic_asm.h> 57# -- Begin static_func 58 .text 59 .align __bionic_asm_align 60 .type static_func, @function 61static_func: 62..B1.1: 63 call ..L2 64..L2: 65 popl %eax 66 lea _GLOBAL_OFFSET_TABLE_+[. - ..L2](%eax), %eax 67 lea static_const_table@GOTOFF(%eax), %eax 68 ret 69 .size static_func,.-static_func 70# -- End static_func 71 72# -- Begin log1p 73ENTRY(log1p) 74# parameter 1: 8 + %ebp 75..B2.1: 76..B2.2: 77 pushl %ebp 78 movl %esp, %ebp 79 subl $104, %esp 80 movl %ebx, 40(%esp) 81 call static_func 82 movl %eax, %ebx 83 movsd 112(%esp), %xmm0 84 xorpd %xmm2, %xmm2 85 movl $16368, %eax 86 pinsrw $3, %eax, %xmm2 87 xorpd %xmm3, %xmm3 88 movl $32768, %ecx 89 movd %ecx, %xmm4 90 movsd 2128(%ebx), %xmm5 91 pshufd $68, %xmm0, %xmm7 92 movapd %xmm2, %xmm6 93 pextrw $3, %xmm0, %ecx 94 addsd %xmm2, %xmm0 95 movapd %xmm0, %xmm1 96 pextrw $3, %xmm0, %eax 97 subsd %xmm0, %xmm6 98 orpd %xmm2, %xmm0 99 psllq $5, %xmm0 100 psrlq $34, %xmm0 101 subl $16, %eax 102 cmpl $32736, %eax 103 jae .L_2TAG_PACKET_0.0.2 104 addsd %xmm6, %xmm7 105 rcpss %xmm0, %xmm0 106 psllq $12, %xmm1 107 pshufd $228, %xmm5, %xmm6 108 psrlq $12, %xmm1 109 andl $32752, %ecx 110 cmpl $16256, %ecx 111 jb .L_2TAG_PACKET_1.0.2 112 andl $32752, %eax 113 movl $32720, %ecx 114 subl %eax, %ecx 115 pinsrw $3, %ecx, %xmm3 116.L_2TAG_PACKET_2.0.2: 117 mulsd %xmm3, %xmm7 118 paddd %xmm4, %xmm0 119 xorpd %xmm4, %xmm4 120 movl $14336, %ecx 121 pinsrw $3, %ecx, %xmm4 122 orpd %xmm2, %xmm1 123 movd %xmm0, %edx 124 psllq $29, %xmm0 125 andpd %xmm1, %xmm5 126 andpd %xmm6, %xmm0 127 subsd %xmm5, %xmm1 128 paddd %xmm4, %xmm0 129 mulsd %xmm0, %xmm5 130 movl $16352, %ecx 131 subl %ecx, %eax 132 cvtsi2sdl %eax, %xmm4 133 mulsd %xmm0, %xmm7 134 mulsd %xmm0, %xmm1 135 movsd 2064(%ebx), %xmm6 136 movapd 2080(%ebx), %xmm3 137 subsd %xmm2, %xmm5 138 andl $16711680, %edx 139 shrl $12, %edx 140 movapd (%ebx,%edx), %xmm0 141 movapd 2096(%ebx), %xmm2 142 addsd %xmm5, %xmm1 143 movapd %xmm1, %xmm5 144 addsd %xmm7, %xmm1 145 subsd %xmm1, %xmm5 146 addsd %xmm5, %xmm7 147 mulsd %xmm4, %xmm6 148 mulsd 2072(%ebx), %xmm4 149 mulsd %xmm1, %xmm3 150 pshufd $68, %xmm1, %xmm5 151 addsd %xmm6, %xmm0 152 mulpd %xmm5, %xmm2 153 mulpd %xmm5, %xmm5 154 pshufd $228, %xmm0, %xmm6 155 addsd %xmm1, %xmm0 156 addpd 2112(%ebx), %xmm2 157 mulpd %xmm5, %xmm3 158 subsd %xmm0, %xmm6 159 mulsd %xmm1, %xmm2 160 addsd %xmm7, %xmm4 161 mulsd %xmm1, %xmm7 162 addsd %xmm6, %xmm1 163 pshufd $238, %xmm0, %xmm6 164 mulsd %xmm5, %xmm5 165 addsd %xmm6, %xmm4 166 subsd %xmm7, %xmm1 167 addpd %xmm3, %xmm2 168 addsd %xmm4, %xmm1 169 mulpd %xmm5, %xmm2 170 addsd %xmm2, %xmm1 171 pshufd $238, %xmm2, %xmm5 172 addsd %xmm5, %xmm1 173 addsd %xmm1, %xmm0 174 jmp .L_2TAG_PACKET_3.0.2 175.L_2TAG_PACKET_0.0.2: 176 movsd 112(%esp), %xmm0 177 movapd %xmm0, %xmm1 178 addl $16, %eax 179 cmpl $32768, %eax 180 jae .L_2TAG_PACKET_4.0.2 181 cmpl $0, %eax 182 je .L_2TAG_PACKET_5.0.2 183.L_2TAG_PACKET_6.0.2: 184 addsd %xmm0, %xmm0 185 jmp .L_2TAG_PACKET_3.0.2 186.L_2TAG_PACKET_7.0.2: 187 ja .L_2TAG_PACKET_6.0.2 188 cmpl $0, %edx 189 ja .L_2TAG_PACKET_6.0.2 190 jmp .L_2TAG_PACKET_8.0.2 191.L_2TAG_PACKET_4.0.2: 192 movd %xmm1, %edx 193 psrlq $32, %xmm1 194 movd %xmm1, %ecx 195 addl %ecx, %ecx 196 cmpl $-2097152, %ecx 197 jae .L_2TAG_PACKET_7.0.2 198 orl %ecx, %edx 199 cmpl $0, %edx 200 je .L_2TAG_PACKET_5.0.2 201.L_2TAG_PACKET_8.0.2: 202 xorpd %xmm1, %xmm1 203 xorpd %xmm0, %xmm0 204 movl $32752, %eax 205 pinsrw $3, %eax, %xmm1 206 movl $141, %edx 207 mulsd %xmm1, %xmm0 208.L_2TAG_PACKET_9.0.2: 209 movsd %xmm0, (%esp) 210 movsd 112(%esp), %xmm0 211 fldl (%esp) 212 jmp .L_2TAG_PACKET_10.0.2 213.L_2TAG_PACKET_5.0.2: 214 xorpd %xmm1, %xmm1 215 xorpd %xmm0, %xmm0 216 movl $49136, %eax 217 pinsrw $3, %eax, %xmm0 218 divsd %xmm1, %xmm0 219 movl $140, %edx 220 jmp .L_2TAG_PACKET_9.0.2 221.L_2TAG_PACKET_1.0.2: 222 movsd 112(%esp), %xmm0 223 cmpl $15504, %ecx 224 jb .L_2TAG_PACKET_11.0.2 225 movapd 2144(%ebx), %xmm1 226 pshufd $68, %xmm0, %xmm0 227 movapd 2160(%ebx), %xmm2 228 pshufd $68, %xmm0, %xmm4 229 movapd 2176(%ebx), %xmm3 230 mulpd %xmm0, %xmm1 231 xorpd %xmm6, %xmm6 232 mulpd %xmm4, %xmm4 233 addpd %xmm2, %xmm1 234 pshufd $68, %xmm4, %xmm5 235 mulpd %xmm0, %xmm4 236 movl $49120, %eax 237 pinsrw $3, %eax, %xmm6 238 mulpd %xmm0, %xmm1 239 mulsd %xmm4, %xmm4 240 addpd %xmm3, %xmm1 241 mulsd %xmm6, %xmm5 242 mulpd %xmm4, %xmm1 243 pshufd $238, %xmm1, %xmm7 244 addsd %xmm7, %xmm1 245 addsd %xmm5, %xmm1 246 addsd %xmm1, %xmm0 247 jmp .L_2TAG_PACKET_3.0.2 248.L_2TAG_PACKET_11.0.2: 249 cmpl $16, %ecx 250 jb .L_2TAG_PACKET_12.0.2 251 jmp .L_2TAG_PACKET_3.0.2 252.L_2TAG_PACKET_12.0.2: 253 movapd %xmm0, %xmm1 254 mulsd %xmm1, %xmm1 255 jmp .L_2TAG_PACKET_3.0.2 256.L_2TAG_PACKET_3.0.2: 257 movsd %xmm0, 24(%esp) 258 fldl 24(%esp) 259.L_2TAG_PACKET_10.0.2: 260 movl 40(%esp), %ebx 261 movl %ebp, %esp 262 popl %ebp 263 ret 264..B2.3: 265END(log1p) 266# -- End log1p 267 268# Start file scope ASM 269ALIAS_SYMBOL(log1pl, log1p); 270# End file scope ASM 271 .section .rodata, "a" 272 .align 16 273 .align 16 274static_const_table: 275 .long 4277811200 276 .long 1072049730 277 .long 2479318832 278 .long 1026487127 279 .long 2854492160 280 .long 1072033410 281 .long 215631550 282 .long 1025638968 283 .long 1547061248 284 .long 1072017216 285 .long 2886781435 286 .long 1026423395 287 .long 649825280 288 .long 1072001146 289 .long 4281533405 290 .long 1024038923 291 .long 646346752 292 .long 1071985198 293 .long 1562735921 294 .long 1023790276 295 .long 2203734016 296 .long 1071969370 297 .long 1838397691 298 .long 3173936209 299 .long 1872169984 300 .long 1071953661 301 .long 3981202460 302 .long 1022325013 303 .long 669557760 304 .long 1071938069 305 .long 4182597802 306 .long 3173174122 307 .long 4076413952 308 .long 1071922591 309 .long 1209029111 310 .long 3170736207 311 .long 556125184 312 .long 1071907228 313 .long 821086028 314 .long 3173437049 315 .long 204914688 316 .long 1071891976 317 .long 2097025986 318 .long 3171071798 319 .long 387545088 320 .long 1071876834 321 .long 3142936996 322 .long 3173092218 323 .long 2912783360 324 .long 1071861800 325 .long 2502420140 326 .long 1024505919 327 .long 1144260608 328 .long 1071846874 329 .long 3315658140 330 .long 3173469843 331 .long 1471209472 332 .long 1071832053 333 .long 129621009 334 .long 3172443877 335 .long 1829683200 336 .long 1071817336 337 .long 3885467693 338 .long 1025535275 339 .long 288676864 340 .long 1071802722 341 .long 86139472 342 .long 3171639793 343 .long 3636378624 344 .long 1071788208 345 .long 1850238587 346 .long 1024654342 347 .long 1606817792 348 .long 1071773795 349 .long 3388899795 350 .long 3173675586 351 .long 1236164608 352 .long 1071759480 353 .long 3983599207 354 .long 1020046558 355 .long 1089616896 356 .long 1071745262 357 .long 4171974224 358 .long 1024773198 359 .long 4143093760 360 .long 1071731139 361 .long 2727587401 362 .long 3173965207 363 .long 600267776 364 .long 1071717112 365 .long 3147685042 366 .long 3173353031 367 .long 2249313280 368 .long 1071703177 369 .long 125835074 370 .long 1025255832 371 .long 3805303808 372 .long 1071689334 373 .long 2289991207 374 .long 1025460331 375 .long 87278592 376 .long 1071675583 377 .long 1106114045 378 .long 1025933602 379 .long 3195405312 380 .long 1071661920 381 .long 3885316576 382 .long 3171206239 383 .long 3853649920 384 .long 1071648346 385 .long 2977069852 386 .long 3171236771 387 .long 2944026624 388 .long 1071625048 389 .long 1008093493 390 .long 1023444474 391 .long 3993180160 392 .long 1071598247 393 .long 1862355595 394 .long 1024642533 395 .long 1454641152 396 .long 1071571617 397 .long 1514603089 398 .long 1026500596 399 .long 3286085632 400 .long 1071545154 401 .long 1400028424 402 .long 3173279056 403 .long 438773760 404 .long 1071518858 405 .long 120727864 406 .long 3172148914 407 .long 1212979200 408 .long 1071492725 409 .long 1625055594 410 .long 3172901933 411 .long 1189017600 412 .long 1071466754 413 .long 3920062376 414 .long 1025727407 415 .long 403064832 416 .long 1071440943 417 .long 1053271728 418 .long 3171391427 419 .long 3343210496 420 .long 1071415289 421 .long 3243395502 422 .long 3173627613 423 .long 1765777408 424 .long 1071389792 425 .long 2145968512 426 .long 1026354304 427 .long 461430784 428 .long 1071364449 429 .long 4094322285 430 .long 1026021467 431 .long 71706624 432 .long 1071339258 433 .long 763632021 434 .long 1024496933 435 .long 1380503552 436 .long 1071314217 437 .long 1383547992 438 .long 3173088453 439 .long 1015732224 440 .long 1071289325 441 .long 3198646877 442 .long 1025390322 443 .long 35977216 444 .long 1071264580 445 .long 2141026805 446 .long 1025754693 447 .long 3927306240 448 .long 1071239979 449 .long 282116272 450 .long 3173394334 451 .long 1125341184 452 .long 1071215523 453 .long 2768427504 454 .long 3172279059 455 .long 1666971648 456 .long 1071191208 457 .long 786837629 458 .long 3172427445 459 .long 2827694080 460 .long 1071167033 461 .long 3857122416 462 .long 3173014241 463 .long 2003683328 464 .long 1071142997 465 .long 859010954 466 .long 1026545007 467 .long 1004017664 468 .long 1071119098 469 .long 3356644970 470 .long 3173458064 471 .long 1753020416 472 .long 1071095334 473 .long 788338552 474 .long 1026157693 475 .long 1992718336 476 .long 1071071704 477 .long 1239179443 478 .long 1026394889 479 .long 3870234624 480 .long 1071048206 481 .long 2082614663 482 .long 1024926053 483 .long 1050437632 484 .long 1071024840 485 .long 660007840 486 .long 1025548499 487 .long 188395520 488 .long 1071001603 489 .long 3878792704 490 .long 3173889571 491 .long 3747176448 492 .long 1070978493 493 .long 144991708 494 .long 3171552042 495 .long 1405669376 496 .long 1070955511 497 .long 3999088879 498 .long 1025486317 499 .long 121151488 500 .long 1070932654 501 .long 2170865497 502 .long 1026473584 503 .long 2652319744 504 .long 1070909920 505 .long 453695652 506 .long 3173916809 507 .long 3262236672 508 .long 1070887309 509 .long 157800053 510 .long 3173984206 511 .long 601221120 512 .long 1070864820 513 .long 3968917661 514 .long 1023992886 515 .long 1999843328 516 .long 1070842450 517 .long 3053895004 518 .long 1024998228 519 .long 1992167424 520 .long 1070820199 521 .long 2968614856 522 .long 1024552653 523 .long 3788726272 524 .long 1070798065 525 .long 3542170808 526 .long 3173573242 527 .long 2094829568 528 .long 1070776048 529 .long 1246758132 530 .long 1026202874 531 .long 288675840 532 .long 1070754146 533 .long 3747328950 534 .long 1026331585 535 .long 1829681152 536 .long 1070732357 537 .long 3125197546 538 .long 1024100318 539 .long 1666869248 540 .long 1070710681 541 .long 1363656119 542 .long 1026336493 543 .long 3417110528 544 .long 1070689116 545 .long 4154791553 546 .long 1026267853 547 .long 2183653376 548 .long 1070667662 549 .long 1671819292 550 .long 3173785870 551 .long 1734434816 552 .long 1070646317 553 .long 373091049 554 .long 1025972363 555 .long 1615681536 556 .long 1070625080 557 .long 384650897 558 .long 1022926043 559 .long 1445382144 560 .long 1070603950 561 .long 344320330 562 .long 3172397196 563 .long 1823715328 564 .long 1070569756 565 .long 3389841200 566 .long 1025231852 567 .long 3839688704 568 .long 1070527917 569 .long 1706790417 570 .long 3167363349 571 .long 4293332992 572 .long 1070486286 573 .long 1614935088 574 .long 1019351591 575 .long 2966720512 576 .long 1070444861 577 .long 4145393717 578 .long 3173711658 579 .long 4066729984 580 .long 1070403639 581 .long 1974925028 582 .long 3171437182 583 .long 3337621504 584 .long 1070362619 585 .long 3314953170 586 .long 3169971314 587 .long 943448064 588 .long 1070321799 589 .long 1498682038 590 .long 3173862340 591 .long 1465634816 592 .long 1070281176 593 .long 1319952810 594 .long 3171693965 595 .long 1015734272 596 .long 1070240749 597 .long 1347821929 598 .long 3173544515 599 .long 118001664 600 .long 1070200516 601 .long 1751482746 602 .long 1026134093 603 .long 3707174912 604 .long 1070160474 605 .long 1486946159 606 .long 1023930920 607 .long 3946381312 608 .long 1070120623 609 .long 2867408081 610 .long 3171368276 611 .long 1699848192 612 .long 1070080961 613 .long 2590187139 614 .long 1025379803 615 .long 2235846656 616 .long 1070041485 617 .long 1888568069 618 .long 3172754960 619 .long 2339729408 620 .long 1070002194 621 .long 3852214753 622 .long 3173323149 623 .long 3196850176 624 .long 1069963086 625 .long 742141560 626 .long 1025101707 627 .long 1800683520 628 .long 1069924160 629 .long 3949500444 630 .long 3172102179 631 .long 3835801600 632 .long 1069885413 633 .long 3848895943 634 .long 1025913832 635 .long 2201202688 636 .long 1069846845 637 .long 1425913464 638 .long 1025868665 639 .long 2778279936 640 .long 1069808453 641 .long 2120889677 642 .long 3173831128 643 .long 2954203136 644 .long 1069770236 645 .long 592147081 646 .long 1019621288 647 .long 210141184 648 .long 1069732193 649 .long 3414275233 650 .long 1023647084 651 .long 709476352 652 .long 1069694321 653 .long 2413027164 654 .long 1024462115 655 .long 2116284416 656 .long 1069656619 657 .long 1144559924 658 .long 1026336654 659 .long 2183651328 660 .long 1069619086 661 .long 3459057650 662 .long 1025634168 663 .long 3047047168 664 .long 1069581720 665 .long 1879674924 666 .long 3173508573 667 .long 970711040 668 .long 1069541521 669 .long 1335954173 670 .long 3173332182 671 .long 2198478848 672 .long 1069467449 673 .long 2951103968 674 .long 3173892200 675 .long 1669611520 676 .long 1069393703 677 .long 531044147 678 .long 1025149248 679 .long 29114368 680 .long 1069320280 681 .long 3327831251 682 .long 1025918673 683 .long 2376949760 684 .long 1069247176 685 .long 737634533 686 .long 3172176000 687 .long 1085390848 688 .long 1069174390 689 .long 3108243400 690 .long 3171828406 691 .long 1566130176 692 .long 1069101918 693 .long 985483226 694 .long 1025708380 695 .long 792780800 696 .long 1069029758 697 .long 4184866295 698 .long 1024426204 699 .long 183156736 700 .long 1068957907 701 .long 2845699378 702 .long 1022107277 703 .long 1301782528 704 .long 1068886362 705 .long 1012735262 706 .long 3173804294 707 .long 1562411008 708 .long 1068815121 709 .long 2197086703 710 .long 3170187813 711 .long 2815549440 712 .long 1068744181 713 .long 2782613207 714 .long 1026345054 715 .long 2756124672 716 .long 1068673540 717 .long 2929486205 718 .long 3173037800 719 .long 3511050240 720 .long 1068603195 721 .long 1443733147 722 .long 3173331549 723 .long 3047047168 724 .long 1068533144 725 .long 1879674924 726 .long 3172459997 727 .long 3221667840 728 .long 1068427825 729 .long 1338588027 730 .long 3171815742 731 .long 3453861888 732 .long 1068288883 733 .long 1205348359 734 .long 3172624626 735 .long 3506110464 736 .long 1068150514 737 .long 893105198 738 .long 1025571866 739 .long 346013696 740 .long 1068012714 741 .long 3495569021 742 .long 3172563349 743 .long 4074029056 744 .long 1067875476 745 .long 3961106338 746 .long 3171065595 747 .long 3559784448 748 .long 1067738798 749 .long 1975385384 750 .long 3173783155 751 .long 797769728 752 .long 1067602675 753 .long 3760305787 754 .long 1026047642 755 .long 2313633792 756 .long 1067467101 757 .long 1559353171 758 .long 1023480256 759 .long 3960766464 760 .long 1067213778 761 .long 1067365107 762 .long 1025865926 763 .long 684261376 764 .long 1066944805 765 .long 844762164 766 .long 3173687482 767 .long 630718464 768 .long 1066676905 769 .long 2458269694 770 .long 1024033081 771 .long 1486061568 772 .long 1066410070 773 .long 115537874 774 .long 3173243995 775 .long 2743664640 776 .long 1065886792 777 .long 3665098304 778 .long 3173471607 779 .long 1971912704 780 .long 1065357333 781 .long 2577214440 782 .long 3171993451 783 .long 1498939392 784 .long 1064306693 785 .long 3409036923 786 .long 1025599151 787 .long 0 788 .long 0 789 .long 0 790 .long 2147483648 791 .long 4277811200 792 .long 1067855426 793 .long 2479318832 794 .long 1022292823 795 .long 2454267026 796 .long 1069697316 797 .long 0 798 .long 3218079744 799 .long 1030730101 800 .long 3217380702 801 .long 1431655765 802 .long 1070945621 803 .long 2576980378 804 .long 1070176665 805 .long 0 806 .long 3219128320 807 .long 0 808 .long 4294959104 809 .long 0 810 .long 4294959104 811 .long 0 812 .long 3217031168 813 .long 2576980378 814 .long 1070176665 815 .long 2454267026 816 .long 1069697316 817 .long 0 818 .long 3218079744 819 .long 1431655765 820 .long 3217380693 821 .long 1431655765 822 .long 1070945621 823 .type static_const_table,@object 824 .size static_const_table,2192 825 .data 826 .section .note.GNU-stack, "" 827# End 828