asm{a,b}: section hax, finally
[uebersetzerbau-ss10.git] / asmb / asmb.s
1         .file   "asmb.c"
2 .section .rodata
3 .align 128
4 const9a:
5         .rept 16
6         .byte 0x9a
7         .endr
8 const20:
9         .rept 16
10         .byte 0x20
11         .endr
12 const3f:
13         .rept 16
14         .byte 0x3f
15         .endr
16
17         .text
18 .globl asmb
19         .type   asmb, @function
20 asmb:
21 .LFB2:
22         xor %rdx, %rdx
23
24         //soll einfach null sein
25         pxor %xmm14, %xmm14
26
27         /*init %xmm8 mit "'Z' + 1 + min_t - 'A'" fuer jedes byte
28         * 'Z' + 1 + min_t - 'A' = 90 + 1 - 128 - 65 = -102
29         * 102 = 01100110
30         * ~102 = 10011001
31         * (~102)+1 = 10011010 = 0x9A */
32         movdqa const9a, %xmm8
33
34         //init %xmm9 mit "'a'-'A'= 97-65 = 32 = 0x20
35         movdqa const20, %xmm9
36
37         /*addiere in %xmm11 "min_t-'A'"
38         * = -128 - 65 = 63 = 0x3f */
39         movdqa const3f, %xmm10
40
41 .nextround:
42         //speicheradresse des pointers zeigt auf 16*8 feld = 128bit
43         movdqu (%rdi, %rdx, 8), %xmm11
44         movdqu (%rdi, %rdx, 8), %xmm12
45
46         //c+min_t-'A'
47         paddb %xmm10, %xmm11
48
49         //0x9a9a... zwischenspeichern
50         movdqa %xmm8, %xmm15
51
52         /*"Packed COMpare Greater Than (Byte)"
53         * X = 'Z' + 1 + min_t - 'A' > c + min_t - 'A' ? 0xff : 0
54         * achtung beim intuitiven lesen des befehles. 'kleiner' 
55         * ist mit 'groesser' vertauscht und vice versa */
56         pcmpgtb %xmm11, %xmm15
57
58 .differenz:
59         //Y = min(X, 'a' - 'A')
60         pminub %xmm9, %xmm15
61
62         //c += Y
63         paddb %xmm15, %xmm12
64
65         //retuniere an die richtige speicheradresse
66         movapd %xmm12, (%rdi, %rdx, 8)
67
68         //entspricht ein byte dem nullbyte dann steht an jener stelle 0xff sonst 0x00
69         pcmpeqb %xmm14, %xmm12
70         //hol die MSBs aller bytes raus
71         pmovmskb %xmm12, %ecx
72         add $2, %rdx
73
74         //ist %ecx gleich null? dann die naechsten 16byte bitte
75         jecxz .nextround
76
77         //speicheradresse des parameters zurueckgeben (wird noch modifziert)
78         mov %rdi, %rax
79
80         /*===============
81         * ab hier uebler hax um nach \0 trotzdem die gleichen bytes wie
82         * input zu haben, also um selbiges verhalten wie asmb_ref zu erzwingen */
83
84         //\0 byte stelle durch rausfinden des MSB des %ecx
85         bsf %ecx, %r11d
86
87         //das ergebnis zweimal abspeichern
88         mov %r11d, %ecx
89
90         //hint: in %xmm15 ist differenz gespeichert (vgl .differenz)
91
92         //leider shiften nur mit immediate! :(
93         btr $3, %r11d
94         jnc .rechtsshift1
95         psrldq $8, %xmm15
96
97 .rechtsshift1:
98         btr $2, %r11d
99         jnc .rechtsshift2
100         psrldq $4, %xmm15
101
102 .rechtsshift2:
103         btr $1, %r11d
104         jnc .rechtsshift3
105         psrldq $2, %xmm15
106
107 .rechtsshift3:
108         btr $0, %r11d
109         jnc .linksshift
110         psrldq $1, %xmm15
111 #==================
112 .linksshift:
113         btr $3, %ecx
114         jnc .linksshift1
115         pslldq $8, %xmm15
116
117 .linksshift1:
118         btr $2, %ecx
119         jnc .linksshift2
120         pslldq $4, %xmm15
121
122 .linksshift2:
123         btr $1, %ecx
124         jnc .linksshift3
125         pslldq $2, %xmm15
126
127 .linksshift3:
128         btr $0, %ecx
129         jnc .endshift
130         pslldq $1, %xmm15
131
132 .endshift:
133         //betreffende speicherstelle in %xmm11 laden
134         movdqu -16(%rax, %rdx, 8), %xmm11
135         //und overhead wieder subtrahieren
136         psubb %xmm15, %xmm11
137
138         //ergebnis zurueckspielen und fertig \o/
139         movapd %xmm11, -16(%rax, %rdx, 8)
140
141         ret
142 .LFE2:
143         .size   asmb, .-asmb
144         .section        .eh_frame,"a",@progbits
145 .Lframe1:
146         .long   .LECIE1-.LSCIE1
147 .LSCIE1:
148         .long   0x0
149         .byte   0x1
150         .string "zR"
151         .uleb128 0x1
152         .sleb128 -8
153         .byte   0x10
154         .uleb128 0x1
155         .byte   0x3
156         .byte   0xc
157         .uleb128 0x7
158         .uleb128 0x8
159         .byte   0x90
160         .uleb128 0x1
161         .align 8
162 .LECIE1:
163 .LSFDE1:
164         .long   .LEFDE1-.LASFDE1
165 .LASFDE1:
166         .long   .LASFDE1-.Lframe1
167         .long   .LFB2
168         .long   .LFE2-.LFB2
169         .uleb128 0x0
170         .align 8
171 .LEFDE1:
172         .ident  "GCC: (Debian 4.3.2-1.1) 4.3.2"
173         .section        .note.GNU-stack,"",@progbits