asma: vllt ist dieses 'min_t -'A'' doch nicht zum vernachlaessigen...
[uebersetzerbau-ss10.git] / asma / asma.s
1         .file   "asma.c"
2         .text
3 .globl asma
4         .type   asma, @function
5 asma:
6 .LFB2:
7
8 /* unsigned char *asma(unsigned char *s)  
9 {  
10   int i;  
11   for (i=0; i<16; i++) {  
12     unsigned char c=s[i];  
13     c += (c>=’A’ && c<=’Z’) ? ’a’-’A’ : 0;  
14     s[i] = c;  
15   }  
16   return s;  
17 }
18
19 Schreiben Sie diese Funktion in Assembler unter Verwendung von pcmpgtb. Dabei ist folgende Äquivalenz hilfreich:
20 (c>=’A’ && c<=’Z’) ? ’a’-’A’ : 0;
21
22 ist (bei Verwendung von Überlauf-Arithmetik) äquivalent zu
23 min(’Z’+1+min_t-’A’ > c+min_t-’A’ ? 0xff : 0, ’a’-’A’)
24
25 wobei min_t der minimale Wert des Datentyps ist, den der Vergleich behandelt (bei pcmpgtb also -128). Zusätzlich zu dem oben genannten dürften die Befehle pminub, paddb, und psubb nützlich sein. */
26         pxor %xmm1, %xmm1
27         pxor %xmm2, %xmm2
28         pxor %xmm2, %xmm3
29         pxor %xmm2, %xmm4
30         pxor %xmm2, %xmm5
31
32         #init %xmm2 mit "'Z' + 1 + min_t - 'A'" fuer jedes byte
33         #'Z' + 1 + min_t - 'A' = 90 + 1 - 128 - 65 = -102
34         #102 = 01100110
35         #~102 = 10011001
36         #(~102)+1 = 10011010 = 0x9A
37         mov $0x9a9a9a9a9a9a9a9a, %rbx
38         movq %rbx, %xmm2
39         pslldq $8, %xmm2
40         movq %rbx, %xmm2
41
42         #init %xmm4 mit "'a'-'A'= 97-65 = 32 = 0x20
43         mov $0x2020202020202020, %rbx
44         movq %rbx, %xmm4
45         pslldq $8, %xmm4
46         movq %rbx, %xmm4
47
48         #speicheradresse des pointers zeigt auf 16*8 feld = 128bit
49         movdqu (%rdi), %xmm1
50         movdqu (%rdi), %xmm3
51
52         #addiere in %xmm1 "min_t-'A'"
53         # = -128 - 65 = 63 = 0x3f
54         mov $0x3f3f3f3f3f3f3f3f, %rbx
55         movq %rbx, %xmm5
56         pslldq $8, %xmm5
57         movq %rbx, %xmm5
58
59         paddb %xmm5, %xmm1
60
61         #"Packed COMpare Greater Than (Byte)"
62         pcmpgtb %xmm2, %xmm1
63
64         pminub %xmm4, %xmm1
65
66         paddb %xmm1, %xmm3
67
68         movq %xmm3, (%rax)
69         ret
70 .LFE2:
71         .size   asma, .-asma
72         .section        .eh_frame,"a",@progbits
73 .Lframe1:
74         .long   .LECIE1-.LSCIE1
75 .LSCIE1:
76         .long   0x0
77         .byte   0x1
78         .string "zR"
79         .uleb128 0x1
80         .sleb128 -8
81         .byte   0x10
82         .uleb128 0x1
83         .byte   0x3
84         .byte   0xc
85         .uleb128 0x7
86         .uleb128 0x8
87         .byte   0x90
88         .uleb128 0x1
89         .align 8
90 .LECIE1:
91 .LSFDE1:
92         .long   .LEFDE1-.LASFDE1
93 .LASFDE1:
94         .long   .LASFDE1-.Lframe1
95         .long   .LFB2
96         .long   .LFE2-.LFB2
97         .uleb128 0x0
98         .align 8
99 .LEFDE1:
100         .ident  "GCC: (Debian 4.3.2-1.1) 4.3.2"
101         .section        .note.GNU-stack,"",@progbits