Can you shrink it further?

Matthias Bentrup via Digitalmars-d digitalmars-d at puremagic.com
Tue Oct 11 07:49:28 PDT 2016


On Tuesday, 11 October 2016 at 14:24:56 UTC, Andrei Alexandrescu 
wrote:
> On 10/11/2016 03:30 AM, Matthias Bentrup wrote:
>> A branch-free version:
>>
>> void popFront4(ref char[] s) @trusted pure nothrow {
>>   immutable c = s[0];
>>   uint char_length = 1 + (c >= 192) + (c >= 240) + (c >= 248);
>>   s = s.ptr[char_length .. s.length];
>> }
>>
>> Theoretically the char_length could be computed with three sub 
>> and addc
>> instructions, but no compiler is smart enough to detect that.
>
> Interesting. 0x80 should be special-cased and you forgot to 
> check the bounds. So:
>
> void popFront4(ref char[] s) @trusted pure nothrow {
>   immutable c = s[0];
>   if (c < 0x80) {
>     s = s.ptr[1 .. s.length];
>   } else {
>     uint l = 1 + (c >= 192) + (c >= 240) + (c >= 248);
>     s = s.ptr[l <= s.length ? l : s.length .. s.length];
>   }
> }
>
> This generated 27 instructions, i.e. same as the baseline. See:
>
> http://ldc.acomirei.ru/#compilers:!((compiler:ldc,options:'-release+-O3+-boundscheck%3Doff',sourcez:G4ewlgJgBADiMDEBOIB2AXAjACiQUwDMoBjACwEMkBtAXSgGcBKKAAXSQFd709oYP8UVCHSkUAdygBvAFBQoYALaKO6cgCMANnhJQAvAyoAGGgG45CotmJQAPFCMAPABxHms%2BfPr6GAOhjsVJhQvr5%2B2qgA5qJmFgC%2BUHia9DoenkpwSOgkIPi%2B6mDo8OaeUBxgGAo%2BAOwcUAC0UOr0SNgAfjYAPlCYHIwl6YqZ2dwQvuSakbmFpIoD8mBWYFAAfFAAbH1VBpjzDD70/oGKFdhgADTheFGizKFXN6Sx8nEyrzKgkLDwyGjoAEy4QgkCjUOjcJDMNicbi8WACHTCUQSaQWJQqNRaHQ2AwQ4zPSxQax2BwuNwWNLyAD0VICSAU3i4cKKUHIn2gHFQXLwxDw9HolAAnk0QJyIN4yDyANYVSK%2BCxedgHdhHajBe4Q3wRaJPAaveRJFKE4l6AxOAgERgUhVQGlNFplVAQQgVOEEXIOG0Q5VIVVBEJhTXamJ6iyGvDW0oZXLZYi5PD5QrwKAALntSD25FUICginozRqDXT7WI/RtiyJ2DzBfs/2Y3Sr%2Be8a3WjCtpUpnhpAElUMAJl8AKoAFQQ9WcNvk1e8Oz2%2BsGwwY6DGEymSBmcy9StxKrpVBOqEbzUuQeuOrugZVwd18TeMiAA)),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3
>
> But it doesn't seem to check for all errors.
>
>
> Andrei

This is the result I'd like to get, but I can't find a way to 
write it without inline assembly :(

void popFrontAsmIntel(ref char[] s) @trusted pure nothrow {
   immutable c = s[0];
   if (c < 0x80) {
     s = s[1 .. $];
   } else {
     uint l = void;
     asm pure nothrow @nogc {
       mov EAX, 1;
       mov BL, 0xf8-1;
       sub BL, c;
       cmp BL, 0xf8-0xc0;
       adc EAX, 0;
       cmp BL, 0xf8-0xe0;
       adc EAX, 0;
       cmp BL, 0xf8-0xf0;
       adc EAX, 0;
       mov l, EAX;
     }
     s = s[l <= $ ? l : $ .. $];
   }
}



More information about the Digitalmars-d mailing list