File: floating_point.S

package info (click to toggle)
android-platform-art 11.0.0%2Br48-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 78,932 kB
  • sloc: cpp: 459,858; java: 163,268; asm: 22,644; python: 9,815; sh: 6,330; ansic: 4,117; xml: 2,855; perl: 77; makefile: 73
file content (250 lines) | stat: -rw-r--r-- 7,043 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
%def fpcmp(suff="d", nanval="pos"):
/*
 * Compare two floating-point values.  Puts 0, 1, or -1 into the
 * destination register based on the results of the comparison.
 *
 * int compare(x, y) {
 *     if (x == y) {
 *         return 0;
 *     } else if (x < y) {
 *         return -1;
 *     } else if (x > y) {
 *         return 1;
 *     } else {
 *         return nanval ? 1 : -1;
 *     }
 * }
 */
    /* op vAA, vBB, vCC */
    movzbl  3(rPC), %ecx                    # ecx<- CC
    movzbl  2(rPC), %eax                    # eax<- BB
    GET_VREG_XMM${suff} %xmm0, %eax
    xor     %eax, %eax
    ucomis${suff} VREG_ADDRESS(%ecx), %xmm0
    jp      .L${opcode}_nan_is_${nanval}
    je      .L${opcode}_finish
    jb      .L${opcode}_less
.L${opcode}_nan_is_pos:
    incl    %eax
    jmp     .L${opcode}_finish
.L${opcode}_nan_is_neg:
.L${opcode}_less:
    decl    %eax
.L${opcode}_finish:
    SET_VREG %eax, rINST
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def fpcvt(instr="", load="", store="", wide="0"):
/*
 * Generic 32-bit FP conversion operation.
 */
    /* unop vA, vB */
    movzbl  rINSTbl, %ecx                   # ecx <- A+
    sarl    $$4, rINST                      # rINST <- B
    $load   VREG_ADDRESS(rINST)             # %st0 <- vB
    andb    $$0xf, %cl                      # ecx <- A
    $instr
    $store  VREG_ADDRESS(%ecx)              # vA <- %st0
    .if $wide
    CLEAR_WIDE_REF %ecx
    .else
    CLEAR_REF %ecx
    .endif
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def sseBinop(instr="", suff=""):
    movzbl  2(rPC), %ecx                    # ecx <- BB
    movzbl  3(rPC), %eax                    # eax <- CC
    GET_VREG_XMM${suff} %xmm0, %ecx         # %xmm0 <- 1st src
#ifdef MTERP_USE_AVX
    v${instr}${suff} VREG_ADDRESS(%eax), %xmm0, %xmm0
    SET_VREG_XMM${suff} %xmm0, rINST        # vAA <- %xmm0
    vpxor    %xmm0, %xmm0, %xmm0
    vmovs${suff}   %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
#else
    ${instr}${suff} VREG_ADDRESS(%eax), %xmm0
    SET_VREG_XMM${suff} %xmm0, rINST        # vAA <- %xmm0
    pxor    %xmm0, %xmm0
    movs${suff}   %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
#endif
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def sseBinop2Addr(instr="", suff=""):
    movzx   rINSTbl, %ecx                   # ecx <- A+
    andl    $$0xf, %ecx                     # ecx <- A
    GET_VREG_XMM${suff} %xmm0, %ecx         # %xmm0 <- 1st src
    sarl    $$4, rINST                      # rINST<- B
#ifdef MTERP_USE_AVX
    v${instr}${suff} VREG_ADDRESS(rINST), %xmm0, %xmm0
    SET_VREG_XMM${suff} %xmm0, %ecx         # vAA<- %xmm0
    vpxor    %xmm0, %xmm0, %xmm0
    vmovs${suff} %xmm0, VREG_REF_ADDRESS(rINST)  # clear ref
#else
    ${instr}${suff} VREG_ADDRESS(rINST), %xmm0
    SET_VREG_XMM${suff} %xmm0, %ecx         # vAA<- %xmm0
    pxor    %xmm0, %xmm0
    movs${suff} %xmm0, VREG_REF_ADDRESS(rINST)  # clear ref
#endif
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_add_double():
%  sseBinop(instr="adds", suff="d")

%def op_add_double_2addr():
%  sseBinop2Addr(instr="adds", suff="d")

%def op_add_float():
%  sseBinop(instr="adds", suff="s")

%def op_add_float_2addr():
%  sseBinop2Addr(instr="adds", suff="s")

%def op_cmpg_double():
%  fpcmp(suff="d", nanval="pos")

%def op_cmpg_float():
%  fpcmp(suff="s", nanval="pos")

%def op_cmpl_double():
%  fpcmp(suff="d", nanval="neg")

%def op_cmpl_float():
%  fpcmp(suff="s", nanval="neg")

%def op_div_double():
%  sseBinop(instr="divs", suff="d")

%def op_div_double_2addr():
%  sseBinop2Addr(instr="divs", suff="d")

%def op_div_float():
%  sseBinop(instr="divs", suff="s")

%def op_div_float_2addr():
%  sseBinop2Addr(instr="divs", suff="s")

%def op_double_to_float():
%  fpcvt(load="fldl", store="fstps")

%def op_double_to_int():
%  cvtfp_int(srcdouble="1", tgtlong="0")

%def op_double_to_long():
%  cvtfp_int(srcdouble="1", tgtlong="1")

%def op_float_to_double():
%  fpcvt(load="flds", store="fstpl", wide="1")

%def op_float_to_int():
%  cvtfp_int(srcdouble="0", tgtlong="0")

%def op_float_to_long():
%  cvtfp_int(srcdouble="0", tgtlong="1")

%def op_int_to_double():
%  fpcvt(load="fildl", store="fstpl", wide="1")

%def op_int_to_float():
%  fpcvt(load="fildl", store="fstps")

%def op_long_to_double():
%  fpcvt(load="fildll", store="fstpl", wide="1")

%def op_long_to_float():
%  fpcvt(load="fildll", store="fstps")

%def op_mul_double():
%  sseBinop(instr="muls", suff="d")

%def op_mul_double_2addr():
%  sseBinop2Addr(instr="muls", suff="d")

%def op_mul_float():
%  sseBinop(instr="muls", suff="s")

%def op_mul_float_2addr():
%  sseBinop2Addr(instr="muls", suff="s")

%def op_neg_double():
%  fpcvt(instr="fchs", load="fldl", store="fstpl", wide="1")

%def op_neg_float():
%  fpcvt(instr="fchs", load="flds", store="fstps")

%def op_rem_double():
    /* rem_double vAA, vBB, vCC */
    movzbl  3(rPC), %ecx                    # ecx <- BB
    movzbl  2(rPC), %eax                    # eax <- CC
    fldl    VREG_ADDRESS(%ecx)              # %st1 <- fp[vBB]
    fldl    VREG_ADDRESS(%eax)              # %st0 <- fp[vCC]
1:
    fprem
    fstsw   %ax
    sahf
    jp      1b
    fstp    %st(1)
    fstpl   VREG_ADDRESS(rINST)             # fp[vAA] <- %st
    CLEAR_WIDE_REF rINST
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def op_rem_double_2addr():
    /* rem_double/2addr vA, vB */
    movzx   rINSTbl, %ecx                   # ecx <- A+
    sarl    $$4, rINST                      # rINST <- B
    fldl    VREG_ADDRESS(rINST)             # vB to fp stack
    andb    $$0xf, %cl                      # ecx <- A
    fldl    VREG_ADDRESS(%ecx)              # vA to fp stack
1:
    fprem
    fstsw   %ax
    sahf
    jp      1b
    fstp    %st(1)
    fstpl   VREG_ADDRESS(%ecx)              # %st to vA
    CLEAR_WIDE_REF %ecx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_rem_float():
    /* rem_float vAA, vBB, vCC */
    movzbl  3(rPC), %ecx                    # ecx <- BB
    movzbl  2(rPC), %eax                    # eax <- CC
    flds    VREG_ADDRESS(%ecx)              # vBB to fp stack
    flds    VREG_ADDRESS(%eax)              # vCC to fp stack
1:
    fprem
    fstsw   %ax
    sahf
    jp      1b
    fstp    %st(1)
    fstps   VREG_ADDRESS(rINST)             # %st to vAA
    CLEAR_REF rINST
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def op_rem_float_2addr():
    /* rem_float/2addr vA, vB */
    movzx   rINSTbl, %ecx                   # ecx <- A+
    sarl    $$4, rINST                      # rINST <- B
    flds    VREG_ADDRESS(rINST)             # vB to fp stack
    andb    $$0xf, %cl                      # ecx <- A
    flds    VREG_ADDRESS(%ecx)              # vA to fp stack
1:
    fprem
    fstsw   %ax
    sahf
    jp      1b
    fstp    %st(1)
    fstps   VREG_ADDRESS(%ecx)              # %st to vA
    CLEAR_REF %ecx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_sub_double():
%  sseBinop(instr="subs", suff="d")

%def op_sub_double_2addr():
%  sseBinop2Addr(instr="subs", suff="d")

%def op_sub_float():
%  sseBinop(instr="subs", suff="s")

%def op_sub_float_2addr():
%  sseBinop2Addr(instr="subs", suff="s")