asmb: asmb verhaelt sich nun exakt wie asmb_ref
[uebersetzerbau-ss10.git] / asmb / asmb.s
index 9d08b641bb6b0a49638c4c92aa7e7d542719a90a..e94d189c7f0b9bf56cbe620177e8b9760d984400 100644 (file)
@@ -46,6 +46,7 @@ asmb:
        * ist mit 'groesser' vertauscht und vice versa */
        pcmpgtb %xmm11, %xmm15
 
+.differenz:
        //Y = min(X, 'a' - 'A')
        pminub %xmm9, %xmm15
 
@@ -55,7 +56,7 @@ asmb:
        //retuniere an die richtige speicheradresse
        movapd %xmm12, (%rdi, %rdx, 8)
 
-       //ist ein byte groesser als 0? dann steht 0xff drin
+       //entspricht ein byte dem nullbyte dann steht an jener stelle 0xff sonst 0x00
        pcmpeqb %xmm14, %xmm12
        //hol die MSBs aller bytes raus
        pmovmskb %xmm12, %ecx
@@ -64,7 +65,78 @@ asmb:
        //ist %ecx gleich null? dann die naechsten 16byte bitte
        jecxz .nextround
 
+       //speicheradresse des parameters zurueckgeben (wird noch modifziert)
        mov %rdi, %rax
+
+       /*===============
+       * ab hier uebler hax um nach \0 trotzdem die gleichen bytes wie
+       * input zu haben, also um selbiges verhalten wie asmb_ref zu erzwingen */
+
+       //\0 byte stelle durch rausfinden des MSB des %ecx
+       bsf %ecx, %r11d
+
+       //das ergebnis zweimal abspeichern
+       mov %r11d, %ecx
+
+       //hint: in %xmm15 ist differenz gespeichert (vgl .differenz)
+
+       //leider shiften nur mit immediate! :(
+       cmp $8, %r11d
+       jc .rechtsshift1
+       psrldq $8, %xmm15
+       sub $8, %r11d
+
+.rechtsshift1:
+       cmp $4, %r11d
+       jc .rechtsshift2
+       psrldq $4, %xmm15
+       sub $4, %r11d
+
+.rechtsshift2:
+       cmp $2, %r11d
+       jc .rechtsshift3
+       psrldq $2, %xmm15
+       sub $2, %r11d
+
+.rechtsshift3:
+       cmp $1, %r11d
+       jc .linksshift
+       psrldq $1, %xmm15
+       sub $1, %r11d
+#==================
+.linksshift:
+       cmp $8, %ecx
+       jc .linksshift1
+       pslldq $8, %xmm15
+       sub $8, %ecx
+
+.linksshift1:
+       cmp $4, %ecx
+       jc .linksshift2
+       pslldq $4, %xmm15
+       sub $4, %ecx
+
+.linksshift2:
+       cmp $2, %ecx
+       jc .linksshift3
+       pslldq $2, %xmm15
+       sub $2, %ecx
+
+.linksshift3:
+       cmp $1, %ecx
+       jc .endshift
+       pslldq $1, %xmm15
+       sub $1, %ecx
+
+.endshift:
+       //betreffende speicherstelle in %xmm11 laden
+       movdqu -16(%rax, %rdx, 8), %xmm11
+       //und overhead wieder subtrahieren
+       psubb %xmm15, %xmm11
+
+       //ergebnis zurueckspielen und fertig \o/
+       movapd %xmm11, -16(%rax, %rdx, 8)
+
        ret
 .LFE2:
        .size   asmb, .-asmb