xref: /aosp_15_r20/art/runtime/interpreter/mterp/x86ng/floating_point.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def fpcmp(suff="d", nanval="pos"):
2*795d594fSAndroid Build Coastguard Worker/*
3*795d594fSAndroid Build Coastguard Worker * Compare two floating-point values.  Puts 0, 1, or -1 into the
4*795d594fSAndroid Build Coastguard Worker * destination register based on the results of the comparison.
5*795d594fSAndroid Build Coastguard Worker *
6*795d594fSAndroid Build Coastguard Worker * int compare(x, y) {
7*795d594fSAndroid Build Coastguard Worker *     if (x == y) {
8*795d594fSAndroid Build Coastguard Worker *         return 0;
9*795d594fSAndroid Build Coastguard Worker *     } else if (x < y) {
10*795d594fSAndroid Build Coastguard Worker *         return -1;
11*795d594fSAndroid Build Coastguard Worker *     } else if (x > y) {
12*795d594fSAndroid Build Coastguard Worker *         return 1;
13*795d594fSAndroid Build Coastguard Worker *     } else {
14*795d594fSAndroid Build Coastguard Worker *         return nanval ? 1 : -1;
15*795d594fSAndroid Build Coastguard Worker *     }
16*795d594fSAndroid Build Coastguard Worker * }
17*795d594fSAndroid Build Coastguard Worker */
18*795d594fSAndroid Build Coastguard Worker    /* op vAA, vBB, vCC */
19*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                    # ecx<- CC
20*795d594fSAndroid Build Coastguard Worker    movzbl  2(rPC), %eax                    # eax<- BB
21*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMM${suff} %xmm0, %eax
22*795d594fSAndroid Build Coastguard Worker    xor     %eax, %eax
23*795d594fSAndroid Build Coastguard Worker    ucomis${suff} VREG_ADDRESS(%ecx), %xmm0
24*795d594fSAndroid Build Coastguard Worker    jp      .L${opcode}_nan_is_${nanval}
25*795d594fSAndroid Build Coastguard Worker    je      .L${opcode}_finish
26*795d594fSAndroid Build Coastguard Worker    jb      .L${opcode}_less
27*795d594fSAndroid Build Coastguard Worker.L${opcode}_nan_is_pos:
28*795d594fSAndroid Build Coastguard Worker    incl    %eax
29*795d594fSAndroid Build Coastguard Worker    jmp     .L${opcode}_finish
30*795d594fSAndroid Build Coastguard Worker.L${opcode}_nan_is_neg:
31*795d594fSAndroid Build Coastguard Worker.L${opcode}_less:
32*795d594fSAndroid Build Coastguard Worker    decl    %eax
33*795d594fSAndroid Build Coastguard Worker.L${opcode}_finish:
34*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, rINST
35*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
36*795d594fSAndroid Build Coastguard Worker
37*795d594fSAndroid Build Coastguard Worker%def fpcvt(instr="", load="", store="", wide="0"):
38*795d594fSAndroid Build Coastguard Worker/*
39*795d594fSAndroid Build Coastguard Worker * Generic 32-bit FP conversion operation.
40*795d594fSAndroid Build Coastguard Worker */
41*795d594fSAndroid Build Coastguard Worker    /* unop vA, vB */
42*795d594fSAndroid Build Coastguard Worker    movzbl  rINSTbl, %ecx                   # ecx <- A+
43*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
44*795d594fSAndroid Build Coastguard Worker    $load   VREG_ADDRESS(rINST)             # %st0 <- vB
45*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
46*795d594fSAndroid Build Coastguard Worker    $instr
47*795d594fSAndroid Build Coastguard Worker    $store  VREG_ADDRESS(%ecx)              # vA <- %st0
48*795d594fSAndroid Build Coastguard Worker    .if $wide
49*795d594fSAndroid Build Coastguard Worker    CLEAR_WIDE_REF %ecx
50*795d594fSAndroid Build Coastguard Worker    .else
51*795d594fSAndroid Build Coastguard Worker    CLEAR_REF %ecx
52*795d594fSAndroid Build Coastguard Worker    .endif
53*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
54*795d594fSAndroid Build Coastguard Worker
55*795d594fSAndroid Build Coastguard Worker%def sseBinop(instr="", suff=""):
56*795d594fSAndroid Build Coastguard Worker    movzbl  2(rPC), %ecx                    # ecx <- BB
57*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %eax                    # eax <- CC
58*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMM${suff} %xmm0, %ecx         # %xmm0 <- 1st src
59*795d594fSAndroid Build Coastguard Worker#ifdef MTERP_USE_AVX
60*795d594fSAndroid Build Coastguard Worker    v${instr}${suff} VREG_ADDRESS(%eax), %xmm0, %xmm0
61*795d594fSAndroid Build Coastguard Worker    SET_VREG_XMM${suff} %xmm0, rINST        # vAA <- %xmm0
62*795d594fSAndroid Build Coastguard Worker    vpxor    %xmm0, %xmm0, %xmm0
63*795d594fSAndroid Build Coastguard Worker    vmovs${suff}   %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
64*795d594fSAndroid Build Coastguard Worker#else
65*795d594fSAndroid Build Coastguard Worker    ${instr}${suff} VREG_ADDRESS(%eax), %xmm0
66*795d594fSAndroid Build Coastguard Worker    SET_VREG_XMM${suff} %xmm0, rINST        # vAA <- %xmm0
67*795d594fSAndroid Build Coastguard Worker    pxor    %xmm0, %xmm0
68*795d594fSAndroid Build Coastguard Worker    movs${suff}   %xmm0, VREG_REF_ADDRESS(rINST) # clear ref
69*795d594fSAndroid Build Coastguard Worker#endif
70*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
71*795d594fSAndroid Build Coastguard Worker
72*795d594fSAndroid Build Coastguard Worker%def sseBinop2Addr(instr="", suff=""):
73*795d594fSAndroid Build Coastguard Worker    movzx   rINSTbl, %ecx                   # ecx <- A+
74*795d594fSAndroid Build Coastguard Worker    andl    $$0xf, %ecx                     # ecx <- A
75*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMM${suff} %xmm0, %ecx         # %xmm0 <- 1st src
76*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST<- B
77*795d594fSAndroid Build Coastguard Worker#ifdef MTERP_USE_AVX
78*795d594fSAndroid Build Coastguard Worker    v${instr}${suff} VREG_ADDRESS(rINST), %xmm0, %xmm0
79*795d594fSAndroid Build Coastguard Worker    SET_VREG_XMM${suff} %xmm0, %ecx         # vAA<- %xmm0
80*795d594fSAndroid Build Coastguard Worker    vpxor    %xmm0, %xmm0, %xmm0
81*795d594fSAndroid Build Coastguard Worker    vmovs${suff} %xmm0, VREG_REF_ADDRESS(rINST)  # clear ref
82*795d594fSAndroid Build Coastguard Worker#else
83*795d594fSAndroid Build Coastguard Worker    ${instr}${suff} VREG_ADDRESS(rINST), %xmm0
84*795d594fSAndroid Build Coastguard Worker    SET_VREG_XMM${suff} %xmm0, %ecx         # vAA<- %xmm0
85*795d594fSAndroid Build Coastguard Worker    pxor    %xmm0, %xmm0
86*795d594fSAndroid Build Coastguard Worker    movs${suff} %xmm0, VREG_REF_ADDRESS(rINST)  # clear ref
87*795d594fSAndroid Build Coastguard Worker#endif
88*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
89*795d594fSAndroid Build Coastguard Worker
90*795d594fSAndroid Build Coastguard Worker%def op_add_double():
91*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="adds", suff="d")
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker%def op_add_double_2addr():
94*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="adds", suff="d")
95*795d594fSAndroid Build Coastguard Worker
96*795d594fSAndroid Build Coastguard Worker%def op_add_float():
97*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="adds", suff="s")
98*795d594fSAndroid Build Coastguard Worker
99*795d594fSAndroid Build Coastguard Worker%def op_add_float_2addr():
100*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="adds", suff="s")
101*795d594fSAndroid Build Coastguard Worker
102*795d594fSAndroid Build Coastguard Worker%def op_cmpg_double():
103*795d594fSAndroid Build Coastguard Worker%  fpcmp(suff="d", nanval="pos")
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker%def op_cmpg_float():
106*795d594fSAndroid Build Coastguard Worker%  fpcmp(suff="s", nanval="pos")
107*795d594fSAndroid Build Coastguard Worker
108*795d594fSAndroid Build Coastguard Worker%def op_cmpl_double():
109*795d594fSAndroid Build Coastguard Worker%  fpcmp(suff="d", nanval="neg")
110*795d594fSAndroid Build Coastguard Worker
111*795d594fSAndroid Build Coastguard Worker%def op_cmpl_float():
112*795d594fSAndroid Build Coastguard Worker%  fpcmp(suff="s", nanval="neg")
113*795d594fSAndroid Build Coastguard Worker
114*795d594fSAndroid Build Coastguard Worker%def op_div_double():
115*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="divs", suff="d")
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker%def op_div_double_2addr():
118*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="divs", suff="d")
119*795d594fSAndroid Build Coastguard Worker
120*795d594fSAndroid Build Coastguard Worker%def op_div_float():
121*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="divs", suff="s")
122*795d594fSAndroid Build Coastguard Worker
123*795d594fSAndroid Build Coastguard Worker%def op_div_float_2addr():
124*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="divs", suff="s")
125*795d594fSAndroid Build Coastguard Worker
126*795d594fSAndroid Build Coastguard Worker%def op_double_to_float():
127*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="fldl", store="fstps")
128*795d594fSAndroid Build Coastguard Worker
129*795d594fSAndroid Build Coastguard Worker%def op_double_to_int():
130*795d594fSAndroid Build Coastguard Worker%  cvtfp_int(srcdouble="1", tgtlong="0")
131*795d594fSAndroid Build Coastguard Worker
132*795d594fSAndroid Build Coastguard Worker%def op_double_to_long():
133*795d594fSAndroid Build Coastguard Worker%  cvtfp_int(srcdouble="1", tgtlong="1")
134*795d594fSAndroid Build Coastguard Worker
135*795d594fSAndroid Build Coastguard Worker%def op_float_to_double():
136*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="flds", store="fstpl", wide="1")
137*795d594fSAndroid Build Coastguard Worker
138*795d594fSAndroid Build Coastguard Worker%def op_float_to_int():
139*795d594fSAndroid Build Coastguard Worker%  cvtfp_int(srcdouble="0", tgtlong="0")
140*795d594fSAndroid Build Coastguard Worker
141*795d594fSAndroid Build Coastguard Worker%def op_float_to_long():
142*795d594fSAndroid Build Coastguard Worker%  cvtfp_int(srcdouble="0", tgtlong="1")
143*795d594fSAndroid Build Coastguard Worker
144*795d594fSAndroid Build Coastguard Worker%def op_int_to_double():
145*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="fildl", store="fstpl", wide="1")
146*795d594fSAndroid Build Coastguard Worker
147*795d594fSAndroid Build Coastguard Worker%def op_int_to_float():
148*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="fildl", store="fstps")
149*795d594fSAndroid Build Coastguard Worker
150*795d594fSAndroid Build Coastguard Worker%def op_long_to_double():
151*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="fildll", store="fstpl", wide="1")
152*795d594fSAndroid Build Coastguard Worker
153*795d594fSAndroid Build Coastguard Worker%def op_long_to_float():
154*795d594fSAndroid Build Coastguard Worker%  fpcvt(load="fildll", store="fstps")
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker%def op_mul_double():
157*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="muls", suff="d")
158*795d594fSAndroid Build Coastguard Worker
159*795d594fSAndroid Build Coastguard Worker%def op_mul_double_2addr():
160*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="muls", suff="d")
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker%def op_mul_float():
163*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="muls", suff="s")
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker%def op_mul_float_2addr():
166*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="muls", suff="s")
167*795d594fSAndroid Build Coastguard Worker
168*795d594fSAndroid Build Coastguard Worker%def op_neg_double():
169*795d594fSAndroid Build Coastguard Worker%  fpcvt(instr="fchs", load="fldl", store="fstpl", wide="1")
170*795d594fSAndroid Build Coastguard Worker
171*795d594fSAndroid Build Coastguard Worker%def op_neg_float():
172*795d594fSAndroid Build Coastguard Worker%  fpcvt(instr="fchs", load="flds", store="fstps")
173*795d594fSAndroid Build Coastguard Worker
174*795d594fSAndroid Build Coastguard Worker%def op_rem_double():
175*795d594fSAndroid Build Coastguard Worker    /* rem_double vAA, vBB, vCC */
176*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                    # ecx <- BB
177*795d594fSAndroid Build Coastguard Worker    movzbl  2(rPC), %eax                    # eax <- CC
178*795d594fSAndroid Build Coastguard Worker    fldl    VREG_ADDRESS(%ecx)              # %st1 <- fp[vBB]
179*795d594fSAndroid Build Coastguard Worker    fldl    VREG_ADDRESS(%eax)              # %st0 <- fp[vCC]
180*795d594fSAndroid Build Coastguard Worker1:
181*795d594fSAndroid Build Coastguard Worker    fprem
182*795d594fSAndroid Build Coastguard Worker    fstsw   %ax
183*795d594fSAndroid Build Coastguard Worker    sahf
184*795d594fSAndroid Build Coastguard Worker    jp      1b
185*795d594fSAndroid Build Coastguard Worker    fstp    %st(1)
186*795d594fSAndroid Build Coastguard Worker    fstpl   VREG_ADDRESS(rINST)             # fp[vAA] <- %st
187*795d594fSAndroid Build Coastguard Worker    CLEAR_WIDE_REF rINST
188*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
189*795d594fSAndroid Build Coastguard Worker
190*795d594fSAndroid Build Coastguard Worker%def op_rem_double_2addr():
191*795d594fSAndroid Build Coastguard Worker    /* rem_double/2addr vA, vB */
192*795d594fSAndroid Build Coastguard Worker    movzx   rINSTbl, %ecx                   # ecx <- A+
193*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
194*795d594fSAndroid Build Coastguard Worker    fldl    VREG_ADDRESS(rINST)             # vB to fp stack
195*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
196*795d594fSAndroid Build Coastguard Worker    fldl    VREG_ADDRESS(%ecx)              # vA to fp stack
197*795d594fSAndroid Build Coastguard Worker1:
198*795d594fSAndroid Build Coastguard Worker    fprem
199*795d594fSAndroid Build Coastguard Worker    fstsw   %ax
200*795d594fSAndroid Build Coastguard Worker    sahf
201*795d594fSAndroid Build Coastguard Worker    jp      1b
202*795d594fSAndroid Build Coastguard Worker    fstp    %st(1)
203*795d594fSAndroid Build Coastguard Worker    fstpl   VREG_ADDRESS(%ecx)              # %st to vA
204*795d594fSAndroid Build Coastguard Worker    CLEAR_WIDE_REF %ecx
205*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
206*795d594fSAndroid Build Coastguard Worker
207*795d594fSAndroid Build Coastguard Worker%def op_rem_float():
208*795d594fSAndroid Build Coastguard Worker    /* rem_float vAA, vBB, vCC */
209*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                    # ecx <- BB
210*795d594fSAndroid Build Coastguard Worker    movzbl  2(rPC), %eax                    # eax <- CC
211*795d594fSAndroid Build Coastguard Worker    flds    VREG_ADDRESS(%ecx)              # vBB to fp stack
212*795d594fSAndroid Build Coastguard Worker    flds    VREG_ADDRESS(%eax)              # vCC to fp stack
213*795d594fSAndroid Build Coastguard Worker1:
214*795d594fSAndroid Build Coastguard Worker    fprem
215*795d594fSAndroid Build Coastguard Worker    fstsw   %ax
216*795d594fSAndroid Build Coastguard Worker    sahf
217*795d594fSAndroid Build Coastguard Worker    jp      1b
218*795d594fSAndroid Build Coastguard Worker    fstp    %st(1)
219*795d594fSAndroid Build Coastguard Worker    fstps   VREG_ADDRESS(rINST)             # %st to vAA
220*795d594fSAndroid Build Coastguard Worker    CLEAR_REF rINST
221*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
222*795d594fSAndroid Build Coastguard Worker
223*795d594fSAndroid Build Coastguard Worker%def op_rem_float_2addr():
224*795d594fSAndroid Build Coastguard Worker    /* rem_float/2addr vA, vB */
225*795d594fSAndroid Build Coastguard Worker    movzx   rINSTbl, %ecx                   # ecx <- A+
226*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
227*795d594fSAndroid Build Coastguard Worker    flds    VREG_ADDRESS(rINST)             # vB to fp stack
228*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
229*795d594fSAndroid Build Coastguard Worker    flds    VREG_ADDRESS(%ecx)              # vA to fp stack
230*795d594fSAndroid Build Coastguard Worker1:
231*795d594fSAndroid Build Coastguard Worker    fprem
232*795d594fSAndroid Build Coastguard Worker    fstsw   %ax
233*795d594fSAndroid Build Coastguard Worker    sahf
234*795d594fSAndroid Build Coastguard Worker    jp      1b
235*795d594fSAndroid Build Coastguard Worker    fstp    %st(1)
236*795d594fSAndroid Build Coastguard Worker    fstps   VREG_ADDRESS(%ecx)              # %st to vA
237*795d594fSAndroid Build Coastguard Worker    CLEAR_REF %ecx
238*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
239*795d594fSAndroid Build Coastguard Worker
240*795d594fSAndroid Build Coastguard Worker%def op_sub_double():
241*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="subs", suff="d")
242*795d594fSAndroid Build Coastguard Worker
243*795d594fSAndroid Build Coastguard Worker%def op_sub_double_2addr():
244*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="subs", suff="d")
245*795d594fSAndroid Build Coastguard Worker
246*795d594fSAndroid Build Coastguard Worker%def op_sub_float():
247*795d594fSAndroid Build Coastguard Worker%  sseBinop(instr="subs", suff="s")
248*795d594fSAndroid Build Coastguard Worker
249*795d594fSAndroid Build Coastguard Worker%def op_sub_float_2addr():
250*795d594fSAndroid Build Coastguard Worker%  sseBinop2Addr(instr="subs", suff="s")
251