xref: /aosp_15_r20/art/runtime/interpreter/mterp/x86_64ng/arithmetic.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def bindiv(result="", second="", tmp="", wide="", suffix="", rem="0", ext="cdq"):
2*795d594fSAndroid Build Coastguard Worker/*
3*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation.  Handles special case of op1=-1.
4*795d594fSAndroid Build Coastguard Worker */
5*795d594fSAndroid Build Coastguard Worker    /* div/rem vAA, vBB, vCC */
6*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # rax <- BB
7*795d594fSAndroid Build Coastguard Worker    movzbq  3(rPC), %rcx                    # rcx <- CC
8*795d594fSAndroid Build Coastguard Worker    .if $wide
9*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, %rax                # eax <- vBB
10*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG $second, %rcx             # ecx <- vCC
11*795d594fSAndroid Build Coastguard Worker    .else
12*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- vBB
13*795d594fSAndroid Build Coastguard Worker    GET_VREG $second, %rcx                  # ecx <- vCC
14*795d594fSAndroid Build Coastguard Worker    .endif
15*795d594fSAndroid Build Coastguard Worker    test${suffix}   $second, $second
16*795d594fSAndroid Build Coastguard Worker    jz      common_errDivideByZero
17*795d594fSAndroid Build Coastguard Worker    cmp${suffix}  $$-1, $second
18*795d594fSAndroid Build Coastguard Worker    je      2f
19*795d594fSAndroid Build Coastguard Worker    cmp${suffix}  $$2, $second
20*795d594fSAndroid Build Coastguard Worker    je 3f
21*795d594fSAndroid Build Coastguard Worker    $ext                                    # rdx:rax <- sign-extended of rax
22*795d594fSAndroid Build Coastguard Worker    idiv${suffix}   $second
23*795d594fSAndroid Build Coastguard Worker1:
24*795d594fSAndroid Build Coastguard Worker    .if $wide
25*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG $result, rINSTq           # eax <- vBB
26*795d594fSAndroid Build Coastguard Worker    .else
27*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq                # eax <- vBB
28*795d594fSAndroid Build Coastguard Worker    .endif
29*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
30*795d594fSAndroid Build Coastguard Worker2:
31*795d594fSAndroid Build Coastguard Worker    .if $rem
32*795d594fSAndroid Build Coastguard Worker    xor${suffix} $result, $result
33*795d594fSAndroid Build Coastguard Worker    .else
34*795d594fSAndroid Build Coastguard Worker    neg${suffix} $result
35*795d594fSAndroid Build Coastguard Worker    .endif
36*795d594fSAndroid Build Coastguard Worker    jmp     1b
37*795d594fSAndroid Build Coastguard Worker3:
38*795d594fSAndroid Build Coastguard Worker    .if $rem
39*795d594fSAndroid Build Coastguard Worker    mov${suffix} $tmp, $result
40*795d594fSAndroid Build Coastguard Worker    .if $wide
41*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$63, $result
42*795d594fSAndroid Build Coastguard Worker    .else
43*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$31, $result
44*795d594fSAndroid Build Coastguard Worker    .endif
45*795d594fSAndroid Build Coastguard Worker    add${suffix} $tmp, $result
46*795d594fSAndroid Build Coastguard Worker    and${suffix} $$-2, $result
47*795d594fSAndroid Build Coastguard Worker    sub${suffix} $result, $tmp
48*795d594fSAndroid Build Coastguard Worker    mov${suffix} $tmp, $result
49*795d594fSAndroid Build Coastguard Worker    .else
50*795d594fSAndroid Build Coastguard Worker    mov${suffix} $result, $tmp
51*795d594fSAndroid Build Coastguard Worker    .if $wide
52*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$63, $tmp
53*795d594fSAndroid Build Coastguard Worker    .else
54*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$31, $tmp
55*795d594fSAndroid Build Coastguard Worker    .endif
56*795d594fSAndroid Build Coastguard Worker    add${suffix} $tmp, $result
57*795d594fSAndroid Build Coastguard Worker    sar${suffix} $result
58*795d594fSAndroid Build Coastguard Worker    .endif
59*795d594fSAndroid Build Coastguard Worker    jmp     1b
60*795d594fSAndroid Build Coastguard Worker
61*795d594fSAndroid Build Coastguard Worker%def bindiv2addr(result="", second="", tmp="", wide="", suffix="", rem="0", ext="cdq"):
62*795d594fSAndroid Build Coastguard Worker/*
63*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation.  Handles special case of op1=-1.
64*795d594fSAndroid Build Coastguard Worker */
65*795d594fSAndroid Build Coastguard Worker    /* div/rem/2addr vA, vB */
66*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- BA
67*795d594fSAndroid Build Coastguard Worker    sarl    $$4, %ecx                       # rcx <- B
68*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, rINSTbl                  # rINST <- A
69*795d594fSAndroid Build Coastguard Worker    .if $wide
70*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, rINSTq              # eax <- vA
71*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG $second, %rcx             # ecx <- vB
72*795d594fSAndroid Build Coastguard Worker    .else
73*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, rINSTq                   # eax <- vA
74*795d594fSAndroid Build Coastguard Worker    GET_VREG $second, %rcx                  # ecx <- vB
75*795d594fSAndroid Build Coastguard Worker    .endif
76*795d594fSAndroid Build Coastguard Worker    test${suffix}   $second, $second
77*795d594fSAndroid Build Coastguard Worker    jz      common_errDivideByZero
78*795d594fSAndroid Build Coastguard Worker    cmp${suffix}  $$-1, $second
79*795d594fSAndroid Build Coastguard Worker    je      2f
80*795d594fSAndroid Build Coastguard Worker    cmp${suffix}  $$2, $second
81*795d594fSAndroid Build Coastguard Worker    je      3f
82*795d594fSAndroid Build Coastguard Worker    $ext                                    # rdx:rax <- sign-extended of rax
83*795d594fSAndroid Build Coastguard Worker    idiv${suffix}   $second
84*795d594fSAndroid Build Coastguard Worker1:
85*795d594fSAndroid Build Coastguard Worker    .if $wide
86*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG $result, rINSTq           # vA <- result
87*795d594fSAndroid Build Coastguard Worker    .else
88*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq                # vA <- result
89*795d594fSAndroid Build Coastguard Worker    .endif
90*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
91*795d594fSAndroid Build Coastguard Worker2:
92*795d594fSAndroid Build Coastguard Worker    .if $rem
93*795d594fSAndroid Build Coastguard Worker    xor${suffix} $result, $result
94*795d594fSAndroid Build Coastguard Worker    .else
95*795d594fSAndroid Build Coastguard Worker    neg${suffix} $result
96*795d594fSAndroid Build Coastguard Worker    .endif
97*795d594fSAndroid Build Coastguard Worker    jmp     1b
98*795d594fSAndroid Build Coastguard Worker3:
99*795d594fSAndroid Build Coastguard Worker    .if $rem
100*795d594fSAndroid Build Coastguard Worker    mov${suffix} $tmp, $result
101*795d594fSAndroid Build Coastguard Worker    .if $wide
102*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$63, $result
103*795d594fSAndroid Build Coastguard Worker    .else
104*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$31, $result
105*795d594fSAndroid Build Coastguard Worker    .endif
106*795d594fSAndroid Build Coastguard Worker    add${suffix} $tmp, $result
107*795d594fSAndroid Build Coastguard Worker    and${suffix} $$-2, $result
108*795d594fSAndroid Build Coastguard Worker    sub${suffix} $result, $tmp
109*795d594fSAndroid Build Coastguard Worker    mov${suffix} $tmp, $result
110*795d594fSAndroid Build Coastguard Worker    .else
111*795d594fSAndroid Build Coastguard Worker    mov${suffix} $result, $tmp
112*795d594fSAndroid Build Coastguard Worker    .if $wide
113*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$63, $tmp
114*795d594fSAndroid Build Coastguard Worker    .else
115*795d594fSAndroid Build Coastguard Worker    shr${suffix} $$31, $tmp
116*795d594fSAndroid Build Coastguard Worker    .endif
117*795d594fSAndroid Build Coastguard Worker    add${suffix} $tmp, $result
118*795d594fSAndroid Build Coastguard Worker    sar${suffix} $result
119*795d594fSAndroid Build Coastguard Worker    .endif
120*795d594fSAndroid Build Coastguard Worker    jmp     1b
121*795d594fSAndroid Build Coastguard Worker
122*795d594fSAndroid Build Coastguard Worker%def bindivLit16(result="", rem="0"):
123*795d594fSAndroid Build Coastguard Worker/*
124*795d594fSAndroid Build Coastguard Worker * 32-bit binary div/rem operation.  Handles special case of op1=-1.
125*795d594fSAndroid Build Coastguard Worker */
126*795d594fSAndroid Build Coastguard Worker    /* div/rem/lit16 vA, vB, #+CCCC */
127*795d594fSAndroid Build Coastguard Worker    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
128*795d594fSAndroid Build Coastguard Worker    movl    rINST, %eax                     # rax <- 000000BA
129*795d594fSAndroid Build Coastguard Worker    sarl    $$4, %eax                       # eax <- B
130*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- vB
131*795d594fSAndroid Build Coastguard Worker    movswl  2(rPC), %ecx                    # ecx <- ssssCCCC
132*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, rINSTbl                  # rINST <- A
133*795d594fSAndroid Build Coastguard Worker    testl   %ecx, %ecx
134*795d594fSAndroid Build Coastguard Worker    jz      common_errDivideByZero
135*795d594fSAndroid Build Coastguard Worker    cmpl    $$-1, %ecx
136*795d594fSAndroid Build Coastguard Worker    je      2f
137*795d594fSAndroid Build Coastguard Worker    cdq                                     # rax <- sign-extended of eax
138*795d594fSAndroid Build Coastguard Worker    idivl   %ecx
139*795d594fSAndroid Build Coastguard Worker1:
140*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq                # vA <- result
141*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
142*795d594fSAndroid Build Coastguard Worker2:
143*795d594fSAndroid Build Coastguard Worker    .if $rem
144*795d594fSAndroid Build Coastguard Worker    xorl    $result, $result
145*795d594fSAndroid Build Coastguard Worker    .else
146*795d594fSAndroid Build Coastguard Worker    negl    $result
147*795d594fSAndroid Build Coastguard Worker    .endif
148*795d594fSAndroid Build Coastguard Worker    jmp     1b
149*795d594fSAndroid Build Coastguard Worker
150*795d594fSAndroid Build Coastguard Worker%def bindivLit8(result="", rem="0"):
151*795d594fSAndroid Build Coastguard Worker/*
152*795d594fSAndroid Build Coastguard Worker * 32-bit div/rem "lit8" binary operation.  Handles special case of
153*795d594fSAndroid Build Coastguard Worker * op0=minint & op1=-1
154*795d594fSAndroid Build Coastguard Worker */
155*795d594fSAndroid Build Coastguard Worker    /* div/rem/lit8 vAA, vBB, #+CC */
156*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # eax <- BB
157*795d594fSAndroid Build Coastguard Worker    movsbl  3(rPC), %ecx                    # ecx <- ssssssCC
158*795d594fSAndroid Build Coastguard Worker    GET_VREG  %eax, %rax                    # eax <- rBB
159*795d594fSAndroid Build Coastguard Worker    testl   %ecx, %ecx
160*795d594fSAndroid Build Coastguard Worker    je      common_errDivideByZero
161*795d594fSAndroid Build Coastguard Worker    cmpl    $$-1, %ecx
162*795d594fSAndroid Build Coastguard Worker    je      2f
163*795d594fSAndroid Build Coastguard Worker    cdq                                     # rax <- sign-extended of eax
164*795d594fSAndroid Build Coastguard Worker    idivl   %ecx
165*795d594fSAndroid Build Coastguard Worker1:
166*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq                # vA <- result
167*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
168*795d594fSAndroid Build Coastguard Worker2:
169*795d594fSAndroid Build Coastguard Worker    .if $rem
170*795d594fSAndroid Build Coastguard Worker    xorl    $result, $result
171*795d594fSAndroid Build Coastguard Worker    .else
172*795d594fSAndroid Build Coastguard Worker    negl    $result
173*795d594fSAndroid Build Coastguard Worker    .endif
174*795d594fSAndroid Build Coastguard Worker    jmp     1b
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker%def binop(result="%eax", instr=""):
177*795d594fSAndroid Build Coastguard Worker/*
178*795d594fSAndroid Build Coastguard Worker * Generic 32-bit binary operation.  Provide an "instr" line that
179*795d594fSAndroid Build Coastguard Worker * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
180*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call.  (If the result
181*795d594fSAndroid Build Coastguard Worker * comes back in a register other than eax, you can override "result".)
182*795d594fSAndroid Build Coastguard Worker *
183*795d594fSAndroid Build Coastguard Worker * For: add-int, sub-int, and-int, or-int,
184*795d594fSAndroid Build Coastguard Worker *      xor-int, shl-int, shr-int, ushr-int
185*795d594fSAndroid Build Coastguard Worker */
186*795d594fSAndroid Build Coastguard Worker    /* binop vAA, vBB, vCC */
187*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # rax <- BB
188*795d594fSAndroid Build Coastguard Worker    movzbq  3(rPC), %rcx                    # rcx <- CC
189*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- vBB
190*795d594fSAndroid Build Coastguard Worker    $instr VREG_ADDRESS(%rcx),%eax
191*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq
192*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
193*795d594fSAndroid Build Coastguard Worker
194*795d594fSAndroid Build Coastguard Worker%def binop1(wide="0", instr=""):
195*795d594fSAndroid Build Coastguard Worker/*
196*795d594fSAndroid Build Coastguard Worker * Generic 32-bit binary operation in which both operands loaded to
197*795d594fSAndroid Build Coastguard Worker * registers (op0 in eax, op1 in ecx).
198*795d594fSAndroid Build Coastguard Worker */
199*795d594fSAndroid Build Coastguard Worker    /* binop vAA, vBB, vCC */
200*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # eax <- BB
201*795d594fSAndroid Build Coastguard Worker    movzbq  3(rPC), %rcx                    # ecx <- CC
202*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, %rcx                     # eax <- vCC
203*795d594fSAndroid Build Coastguard Worker    .if $wide
204*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, %rax                # rax <- vBB
205*795d594fSAndroid Build Coastguard Worker    $instr                                  # ex: addl    %ecx,%eax
206*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, rINSTq
207*795d594fSAndroid Build Coastguard Worker    .else
208*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- vBB
209*795d594fSAndroid Build Coastguard Worker    $instr                                  # ex: addl    %ecx,%eax
210*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, rINSTq
211*795d594fSAndroid Build Coastguard Worker    .endif
212*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker%def binop2addr(result="%eax", instr=""):
215*795d594fSAndroid Build Coastguard Worker/*
216*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
217*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = r0 op r1".
218*795d594fSAndroid Build Coastguard Worker * This could be an instruction or a function call.
219*795d594fSAndroid Build Coastguard Worker *
220*795d594fSAndroid Build Coastguard Worker * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
221*795d594fSAndroid Build Coastguard Worker *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
222*795d594fSAndroid Build Coastguard Worker *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
223*795d594fSAndroid Build Coastguard Worker *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
224*795d594fSAndroid Build Coastguard Worker */
225*795d594fSAndroid Build Coastguard Worker    /* binop/2addr vA, vB */
226*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
227*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
228*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
229*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, rINSTq                   # eax <- vB
230*795d594fSAndroid Build Coastguard Worker    $instr %eax, VREG_ADDRESS(%rcx)
231*795d594fSAndroid Build Coastguard Worker    CLEAR_REF %rcx
232*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
233*795d594fSAndroid Build Coastguard Worker
234*795d594fSAndroid Build Coastguard Worker%def binopLit16(result="%eax", instr=""):
235*795d594fSAndroid Build Coastguard Worker/*
236*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
237*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = eax op ecx".
238*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call.  (If the result
239*795d594fSAndroid Build Coastguard Worker * comes back in a register other than eax, you can override "result".)
240*795d594fSAndroid Build Coastguard Worker *
241*795d594fSAndroid Build Coastguard Worker * For: add-int/lit16, rsub-int,
242*795d594fSAndroid Build Coastguard Worker *      and-int/lit16, or-int/lit16, xor-int/lit16
243*795d594fSAndroid Build Coastguard Worker */
244*795d594fSAndroid Build Coastguard Worker    /* binop/lit16 vA, vB, #+CCCC */
245*795d594fSAndroid Build Coastguard Worker    movl    rINST, %eax                     # rax <- 000000BA
246*795d594fSAndroid Build Coastguard Worker    sarl    $$4, %eax                       # eax <- B
247*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- vB
248*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, rINSTbl                  # rINST <- A
249*795d594fSAndroid Build Coastguard Worker    movswl  2(rPC), %ecx                    # ecx <- ssssCCCC
250*795d594fSAndroid Build Coastguard Worker    $instr                                  # for example: addl %ecx, %eax
251*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq
252*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
253*795d594fSAndroid Build Coastguard Worker
254*795d594fSAndroid Build Coastguard Worker%def binopLit8(result="%eax", instr=""):
255*795d594fSAndroid Build Coastguard Worker/*
256*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
257*795d594fSAndroid Build Coastguard Worker * that specifies an instruction that performs "result = eax op ecx".
258*795d594fSAndroid Build Coastguard Worker * This could be an x86 instruction or a function call.  (If the result
259*795d594fSAndroid Build Coastguard Worker * comes back in a register other than r0, you can override "result".)
260*795d594fSAndroid Build Coastguard Worker *
261*795d594fSAndroid Build Coastguard Worker * For: add-int/lit8, rsub-int/lit8
262*795d594fSAndroid Build Coastguard Worker *      and-int/lit8, or-int/lit8, xor-int/lit8,
263*795d594fSAndroid Build Coastguard Worker *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
264*795d594fSAndroid Build Coastguard Worker */
265*795d594fSAndroid Build Coastguard Worker    /* binop/lit8 vAA, vBB, #+CC */
266*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # rax <- BB
267*795d594fSAndroid Build Coastguard Worker    movsbl  3(rPC), %ecx                    # rcx <- ssssssCC
268*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax                     # eax <- rBB
269*795d594fSAndroid Build Coastguard Worker    $instr                                  # ex: addl %ecx,%eax
270*795d594fSAndroid Build Coastguard Worker    SET_VREG $result, rINSTq
271*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
272*795d594fSAndroid Build Coastguard Worker
273*795d594fSAndroid Build Coastguard Worker%def binopWide(instr=""):
274*795d594fSAndroid Build Coastguard Worker/*
275*795d594fSAndroid Build Coastguard Worker * Generic 64-bit binary operation.
276*795d594fSAndroid Build Coastguard Worker */
277*795d594fSAndroid Build Coastguard Worker    /* binop vAA, vBB, vCC */
278*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rax                    # eax <- BB
279*795d594fSAndroid Build Coastguard Worker    movzbq  3(rPC), %rcx                    # ecx <- CC
280*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, %rax                # rax <- v[BB]
281*795d594fSAndroid Build Coastguard Worker    $instr VREG_ADDRESS(%rcx),%rax
282*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, rINSTq              # v[AA] <- rax
283*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
284*795d594fSAndroid Build Coastguard Worker
285*795d594fSAndroid Build Coastguard Worker%def binopWide2addr(instr=""):
286*795d594fSAndroid Build Coastguard Worker/*
287*795d594fSAndroid Build Coastguard Worker * Generic 64-bit binary operation.
288*795d594fSAndroid Build Coastguard Worker */
289*795d594fSAndroid Build Coastguard Worker    /* binop/2addr vA, vB */
290*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
291*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
292*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
293*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, rINSTq              # rax <- vB
294*795d594fSAndroid Build Coastguard Worker    $instr %rax,VREG_ADDRESS(%rcx)
295*795d594fSAndroid Build Coastguard Worker    CLEAR_WIDE_REF %rcx
296*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
297*795d594fSAndroid Build Coastguard Worker
298*795d594fSAndroid Build Coastguard Worker%def cvtfp_int(fp_suffix="", i_suffix="", max_const="", result_reg="", wide=""):
299*795d594fSAndroid Build Coastguard Worker/* On fp to int conversions, Java requires that
300*795d594fSAndroid Build Coastguard Worker * if the result > maxint, it should be clamped to maxint.  If it is less
301*795d594fSAndroid Build Coastguard Worker * than minint, it should be clamped to minint.  If it is a nan, the result
302*795d594fSAndroid Build Coastguard Worker * should be zero.  Further, the rounding mode is to truncate.
303*795d594fSAndroid Build Coastguard Worker */
304*795d594fSAndroid Build Coastguard Worker    /* float/double to int/long vA, vB */
305*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
306*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
307*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
308*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMM${fp_suffix} %xmm0, rINSTq
309*795d594fSAndroid Build Coastguard Worker    mov${i_suffix}  ${max_const}, ${result_reg}
310*795d594fSAndroid Build Coastguard Worker    cvtsi2s${fp_suffix}${i_suffix} ${result_reg}, %xmm1
311*795d594fSAndroid Build Coastguard Worker    comis${fp_suffix}    %xmm1, %xmm0
312*795d594fSAndroid Build Coastguard Worker    jae     1f
313*795d594fSAndroid Build Coastguard Worker    jp      2f
314*795d594fSAndroid Build Coastguard Worker    cvtts${fp_suffix}2si${i_suffix}  %xmm0, ${result_reg}
315*795d594fSAndroid Build Coastguard Worker    jmp     1f
316*795d594fSAndroid Build Coastguard Worker2:
317*795d594fSAndroid Build Coastguard Worker    xor${i_suffix}    ${result_reg}, ${result_reg}
318*795d594fSAndroid Build Coastguard Worker1:
319*795d594fSAndroid Build Coastguard Worker    .if $wide
320*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG ${result_reg}, %rcx
321*795d594fSAndroid Build Coastguard Worker    .else
322*795d594fSAndroid Build Coastguard Worker    SET_VREG ${result_reg}, %rcx
323*795d594fSAndroid Build Coastguard Worker    .endif
324*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
325*795d594fSAndroid Build Coastguard Worker
326*795d594fSAndroid Build Coastguard Worker%def shop2addr(wide="0", instr=""):
327*795d594fSAndroid Build Coastguard Worker/*
328*795d594fSAndroid Build Coastguard Worker * Generic 32-bit "shift/2addr" operation.
329*795d594fSAndroid Build Coastguard Worker */
330*795d594fSAndroid Build Coastguard Worker    /* shift/2addr vA, vB */
331*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # ecx <- BA
332*795d594fSAndroid Build Coastguard Worker    sarl    $$4, %ecx                       # ecx <- B
333*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, %rcx                     # ecx <- vBB
334*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, rINSTbl                  # rINST <- A
335*795d594fSAndroid Build Coastguard Worker    .if $wide
336*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, rINSTq              # rax <- vAA
337*795d594fSAndroid Build Coastguard Worker    $instr                                  # ex: sarl %cl, %eax
338*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, rINSTq
339*795d594fSAndroid Build Coastguard Worker    .else
340*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, rINSTq                   # eax <- vAA
341*795d594fSAndroid Build Coastguard Worker    $instr                                  # ex: sarl %cl, %eax
342*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, rINSTq
343*795d594fSAndroid Build Coastguard Worker    .endif
344*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
345*795d594fSAndroid Build Coastguard Worker
346*795d594fSAndroid Build Coastguard Worker%def unop(preinstr="", instr="", wide="0"):
347*795d594fSAndroid Build Coastguard Worker/*
348*795d594fSAndroid Build Coastguard Worker * Generic 32/64-bit unary operation.  Provide an "instr" line that
349*795d594fSAndroid Build Coastguard Worker * specifies an instruction that performs "result = op eax".
350*795d594fSAndroid Build Coastguard Worker */
351*795d594fSAndroid Build Coastguard Worker    /* unop vA, vB */
352*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
353*795d594fSAndroid Build Coastguard Worker    sarl    $$4,rINST                       # rINST <- B
354*795d594fSAndroid Build Coastguard Worker    .if ${wide}
355*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, rINSTq              # rax <- vB
356*795d594fSAndroid Build Coastguard Worker    .else
357*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, rINSTq                   # eax <- vB
358*795d594fSAndroid Build Coastguard Worker    .endif
359*795d594fSAndroid Build Coastguard Worker    andb    $$0xf,%cl                       # ecx <- A
360*795d594fSAndroid Build Coastguard Worker$preinstr
361*795d594fSAndroid Build Coastguard Worker$instr
362*795d594fSAndroid Build Coastguard Worker    .if ${wide}
363*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, %rcx
364*795d594fSAndroid Build Coastguard Worker    .else
365*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, %rcx
366*795d594fSAndroid Build Coastguard Worker    .endif
367*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
368*795d594fSAndroid Build Coastguard Worker
369*795d594fSAndroid Build Coastguard Worker%def op_add_int():
370*795d594fSAndroid Build Coastguard Worker%  binop(instr="addl")
371*795d594fSAndroid Build Coastguard Worker
372*795d594fSAndroid Build Coastguard Worker%def op_add_int_2addr():
373*795d594fSAndroid Build Coastguard Worker%  binop2addr(instr="addl")
374*795d594fSAndroid Build Coastguard Worker
375*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit16():
376*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="addl    %ecx, %eax")
377*795d594fSAndroid Build Coastguard Worker
378*795d594fSAndroid Build Coastguard Worker%def op_add_int_lit8():
379*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="addl    %ecx, %eax")
380*795d594fSAndroid Build Coastguard Worker
381*795d594fSAndroid Build Coastguard Worker%def op_add_long():
382*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="addq")
383*795d594fSAndroid Build Coastguard Worker
384*795d594fSAndroid Build Coastguard Worker%def op_add_long_2addr():
385*795d594fSAndroid Build Coastguard Worker%  binopWide2addr(instr="addq")
386*795d594fSAndroid Build Coastguard Worker
387*795d594fSAndroid Build Coastguard Worker%def op_and_int():
388*795d594fSAndroid Build Coastguard Worker%  binop(instr="andl")
389*795d594fSAndroid Build Coastguard Worker
390*795d594fSAndroid Build Coastguard Worker%def op_and_int_2addr():
391*795d594fSAndroid Build Coastguard Worker%  binop2addr(instr="andl")
392*795d594fSAndroid Build Coastguard Worker
393*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit16():
394*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="andl    %ecx, %eax")
395*795d594fSAndroid Build Coastguard Worker
396*795d594fSAndroid Build Coastguard Worker%def op_and_int_lit8():
397*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="andl    %ecx, %eax")
398*795d594fSAndroid Build Coastguard Worker
399*795d594fSAndroid Build Coastguard Worker%def op_and_long():
400*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="andq")
401*795d594fSAndroid Build Coastguard Worker
402*795d594fSAndroid Build Coastguard Worker%def op_and_long_2addr():
403*795d594fSAndroid Build Coastguard Worker%  binopWide2addr(instr="andq")
404*795d594fSAndroid Build Coastguard Worker
405*795d594fSAndroid Build Coastguard Worker%def op_cmp_long():
406*795d594fSAndroid Build Coastguard Worker/*
407*795d594fSAndroid Build Coastguard Worker * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
408*795d594fSAndroid Build Coastguard Worker * register based on the results of the comparison.
409*795d594fSAndroid Build Coastguard Worker */
410*795d594fSAndroid Build Coastguard Worker    /* cmp-long vAA, vBB, vCC */
411*795d594fSAndroid Build Coastguard Worker    movzbq  2(rPC), %rdx                    # edx <- BB
412*795d594fSAndroid Build Coastguard Worker    movzbq  3(rPC), %rcx                    # ecx <- CC
413*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rdx, %rdx                # rdx <- v[BB]
414*795d594fSAndroid Build Coastguard Worker    xorl    %eax, %eax
415*795d594fSAndroid Build Coastguard Worker    xorl    %edi, %edi
416*795d594fSAndroid Build Coastguard Worker    addb    $$1, %al
417*795d594fSAndroid Build Coastguard Worker    movl    $$-1, %esi
418*795d594fSAndroid Build Coastguard Worker    cmpq    VREG_ADDRESS(%rcx), %rdx
419*795d594fSAndroid Build Coastguard Worker    cmovl   %esi, %edi
420*795d594fSAndroid Build Coastguard Worker    cmovg   %eax, %edi
421*795d594fSAndroid Build Coastguard Worker    SET_VREG %edi, rINSTq
422*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
423*795d594fSAndroid Build Coastguard Worker
424*795d594fSAndroid Build Coastguard Worker%def op_div_int():
425*795d594fSAndroid Build Coastguard Worker%  bindiv(result="%eax", second="%ecx", tmp="%edx", wide="0", suffix="l")
426*795d594fSAndroid Build Coastguard Worker
427*795d594fSAndroid Build Coastguard Worker%def op_div_int_2addr():
428*795d594fSAndroid Build Coastguard Worker%  bindiv2addr(result="%eax", second="%ecx", tmp="%edx", wide="0", suffix="l")
429*795d594fSAndroid Build Coastguard Worker
430*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit16():
431*795d594fSAndroid Build Coastguard Worker%  bindivLit16(result="%eax")
432*795d594fSAndroid Build Coastguard Worker
433*795d594fSAndroid Build Coastguard Worker%def op_div_int_lit8():
434*795d594fSAndroid Build Coastguard Worker%  bindivLit8(result="%eax")
435*795d594fSAndroid Build Coastguard Worker
436*795d594fSAndroid Build Coastguard Worker%def op_div_long():
437*795d594fSAndroid Build Coastguard Worker%  bindiv(result="%rax", second="%rcx", tmp="%rdx", wide="1", suffix="q", ext="cqo")
438*795d594fSAndroid Build Coastguard Worker
439*795d594fSAndroid Build Coastguard Worker%def op_div_long_2addr():
440*795d594fSAndroid Build Coastguard Worker%  bindiv2addr(result="%rax", second="%rcx", tmp="%rdx", wide="1", suffix="q", ext="cqo")
441*795d594fSAndroid Build Coastguard Worker
442*795d594fSAndroid Build Coastguard Worker%def op_int_to_byte():
443*795d594fSAndroid Build Coastguard Worker%  unop(instr="movsbl  %al, %eax")
444*795d594fSAndroid Build Coastguard Worker
445*795d594fSAndroid Build Coastguard Worker%def op_int_to_char():
446*795d594fSAndroid Build Coastguard Worker%  unop(instr="movzwl  %ax,%eax")
447*795d594fSAndroid Build Coastguard Worker
448*795d594fSAndroid Build Coastguard Worker%def op_int_to_long():
449*795d594fSAndroid Build Coastguard Worker    /* int to long vA, vB */
450*795d594fSAndroid Build Coastguard Worker    movzbq  rINSTbl, %rax                   # rax <- +A
451*795d594fSAndroid Build Coastguard Worker    sarl    $$4, %eax                       # eax <- B
452*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, rINSTbl                  # rINST <- A
453*795d594fSAndroid Build Coastguard Worker    movslq  VREG_ADDRESS(%rax), %rax
454*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, rINSTq              # v[A] <- %rax
455*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
456*795d594fSAndroid Build Coastguard Worker
457*795d594fSAndroid Build Coastguard Worker
458*795d594fSAndroid Build Coastguard Worker%def op_int_to_short():
459*795d594fSAndroid Build Coastguard Worker%  unop(instr="movswl %ax, %eax")
460*795d594fSAndroid Build Coastguard Worker
461*795d594fSAndroid Build Coastguard Worker%def op_long_to_int():
462*795d594fSAndroid Build Coastguard Worker/* we ignore the high word, making this equivalent to a 32-bit reg move */
463*795d594fSAndroid Build Coastguard Worker%  op_move()
464*795d594fSAndroid Build Coastguard Worker
465*795d594fSAndroid Build Coastguard Worker%def op_mul_int():
466*795d594fSAndroid Build Coastguard Worker%  binop(instr="imull")
467*795d594fSAndroid Build Coastguard Worker
468*795d594fSAndroid Build Coastguard Worker%def op_mul_int_2addr():
469*795d594fSAndroid Build Coastguard Worker    /* mul vA, vB */
470*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
471*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
472*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
473*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rcx                     # eax <- vA
474*795d594fSAndroid Build Coastguard Worker    imull   (rFP,rINSTq,4), %eax
475*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, %rcx
476*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
477*795d594fSAndroid Build Coastguard Worker
478*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit16():
479*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="imull   %ecx, %eax")
480*795d594fSAndroid Build Coastguard Worker
481*795d594fSAndroid Build Coastguard Worker%def op_mul_int_lit8():
482*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="imull   %ecx, %eax")
483*795d594fSAndroid Build Coastguard Worker
484*795d594fSAndroid Build Coastguard Worker%def op_mul_long():
485*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="imulq")
486*795d594fSAndroid Build Coastguard Worker
487*795d594fSAndroid Build Coastguard Worker%def op_mul_long_2addr():
488*795d594fSAndroid Build Coastguard Worker    /* mul vA, vB */
489*795d594fSAndroid Build Coastguard Worker    movl    rINST, %ecx                     # rcx <- A+
490*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
491*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %cl                      # ecx <- A
492*795d594fSAndroid Build Coastguard Worker    GET_WIDE_VREG %rax, %rcx                # rax <- vA
493*795d594fSAndroid Build Coastguard Worker    imulq   (rFP,rINSTq,4), %rax
494*795d594fSAndroid Build Coastguard Worker    SET_WIDE_VREG %rax, %rcx
495*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
496*795d594fSAndroid Build Coastguard Worker
497*795d594fSAndroid Build Coastguard Worker%def op_neg_int():
498*795d594fSAndroid Build Coastguard Worker%  unop(instr="    negl    %eax")
499*795d594fSAndroid Build Coastguard Worker
500*795d594fSAndroid Build Coastguard Worker%def op_neg_long():
501*795d594fSAndroid Build Coastguard Worker%  unop(instr="    negq    %rax", wide="1")
502*795d594fSAndroid Build Coastguard Worker
503*795d594fSAndroid Build Coastguard Worker%def op_not_int():
504*795d594fSAndroid Build Coastguard Worker%  unop(instr="    notl    %eax")
505*795d594fSAndroid Build Coastguard Worker
506*795d594fSAndroid Build Coastguard Worker%def op_not_long():
507*795d594fSAndroid Build Coastguard Worker%  unop(instr="    notq    %rax", wide="1")
508*795d594fSAndroid Build Coastguard Worker
509*795d594fSAndroid Build Coastguard Worker%def op_or_int():
510*795d594fSAndroid Build Coastguard Worker%  binop(instr="orl")
511*795d594fSAndroid Build Coastguard Worker
512*795d594fSAndroid Build Coastguard Worker%def op_or_int_2addr():
513*795d594fSAndroid Build Coastguard Worker%  binop2addr(instr="orl")
514*795d594fSAndroid Build Coastguard Worker
515*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit16():
516*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="orl     %ecx, %eax")
517*795d594fSAndroid Build Coastguard Worker
518*795d594fSAndroid Build Coastguard Worker%def op_or_int_lit8():
519*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="orl     %ecx, %eax")
520*795d594fSAndroid Build Coastguard Worker
521*795d594fSAndroid Build Coastguard Worker%def op_or_long():
522*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="orq")
523*795d594fSAndroid Build Coastguard Worker
524*795d594fSAndroid Build Coastguard Worker%def op_or_long_2addr():
525*795d594fSAndroid Build Coastguard Worker%  binopWide2addr(instr="orq")
526*795d594fSAndroid Build Coastguard Worker
527*795d594fSAndroid Build Coastguard Worker%def op_rem_int():
528*795d594fSAndroid Build Coastguard Worker%  bindiv(result="%edx", second="%ecx", tmp="%eax", wide="0", suffix="l", rem="1")
529*795d594fSAndroid Build Coastguard Worker
530*795d594fSAndroid Build Coastguard Worker%def op_rem_int_2addr():
531*795d594fSAndroid Build Coastguard Worker%  bindiv2addr(result="%edx", second="%ecx", tmp="%eax", wide="0", suffix="l", rem="1")
532*795d594fSAndroid Build Coastguard Worker
533*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit16():
534*795d594fSAndroid Build Coastguard Worker%  bindivLit16(result="%edx", rem="1")
535*795d594fSAndroid Build Coastguard Worker
536*795d594fSAndroid Build Coastguard Worker%def op_rem_int_lit8():
537*795d594fSAndroid Build Coastguard Worker%  bindivLit8(result="%edx", rem="1")
538*795d594fSAndroid Build Coastguard Worker
539*795d594fSAndroid Build Coastguard Worker%def op_rem_long():
540*795d594fSAndroid Build Coastguard Worker%  bindiv(result="%rdx", second="%rcx", tmp="%rax", wide="1", suffix="q", ext="cqo", rem="1")
541*795d594fSAndroid Build Coastguard Worker
542*795d594fSAndroid Build Coastguard Worker%def op_rem_long_2addr():
543*795d594fSAndroid Build Coastguard Worker%  bindiv2addr(result="%rdx", second="%rcx", tmp="%rax", wide="1", suffix="q", rem="1", ext="cqo")
544*795d594fSAndroid Build Coastguard Worker
545*795d594fSAndroid Build Coastguard Worker%def op_rsub_int():
546*795d594fSAndroid Build Coastguard Worker/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
547*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="subl    %eax, %ecx", result="%ecx")
548*795d594fSAndroid Build Coastguard Worker
549*795d594fSAndroid Build Coastguard Worker%def op_rsub_int_lit8():
550*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="subl    %eax, %ecx", result="%ecx")
551*795d594fSAndroid Build Coastguard Worker
552*795d594fSAndroid Build Coastguard Worker%def op_shl_int():
553*795d594fSAndroid Build Coastguard Worker%  binop1(instr="sall    %cl, %eax")
554*795d594fSAndroid Build Coastguard Worker
555*795d594fSAndroid Build Coastguard Worker%def op_shl_int_2addr():
556*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="sall    %cl, %eax")
557*795d594fSAndroid Build Coastguard Worker
558*795d594fSAndroid Build Coastguard Worker%def op_shl_int_lit8():
559*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="sall    %cl, %eax")
560*795d594fSAndroid Build Coastguard Worker
561*795d594fSAndroid Build Coastguard Worker%def op_shl_long():
562*795d594fSAndroid Build Coastguard Worker%  binop1(instr="salq    %cl, %rax", wide="1")
563*795d594fSAndroid Build Coastguard Worker
564*795d594fSAndroid Build Coastguard Worker%def op_shl_long_2addr():
565*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="salq    %cl, %rax", wide="1")
566*795d594fSAndroid Build Coastguard Worker
567*795d594fSAndroid Build Coastguard Worker%def op_shr_int():
568*795d594fSAndroid Build Coastguard Worker%  binop1(instr="sarl    %cl, %eax")
569*795d594fSAndroid Build Coastguard Worker
570*795d594fSAndroid Build Coastguard Worker%def op_shr_int_2addr():
571*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="sarl    %cl, %eax")
572*795d594fSAndroid Build Coastguard Worker
573*795d594fSAndroid Build Coastguard Worker%def op_shr_int_lit8():
574*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="sarl    %cl, %eax")
575*795d594fSAndroid Build Coastguard Worker
576*795d594fSAndroid Build Coastguard Worker%def op_shr_long():
577*795d594fSAndroid Build Coastguard Worker%  binop1(instr="sarq    %cl, %rax", wide="1")
578*795d594fSAndroid Build Coastguard Worker
579*795d594fSAndroid Build Coastguard Worker%def op_shr_long_2addr():
580*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="sarq    %cl, %rax", wide="1")
581*795d594fSAndroid Build Coastguard Worker
582*795d594fSAndroid Build Coastguard Worker%def op_sub_int():
583*795d594fSAndroid Build Coastguard Worker%  binop(instr="subl")
584*795d594fSAndroid Build Coastguard Worker
585*795d594fSAndroid Build Coastguard Worker%def op_sub_int_2addr():
586*795d594fSAndroid Build Coastguard Worker%  binop2addr(instr="subl")
587*795d594fSAndroid Build Coastguard Worker
588*795d594fSAndroid Build Coastguard Worker%def op_sub_long():
589*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="subq")
590*795d594fSAndroid Build Coastguard Worker
591*795d594fSAndroid Build Coastguard Worker%def op_sub_long_2addr():
592*795d594fSAndroid Build Coastguard Worker%  binopWide2addr(instr="subq")
593*795d594fSAndroid Build Coastguard Worker
594*795d594fSAndroid Build Coastguard Worker%def op_ushr_int():
595*795d594fSAndroid Build Coastguard Worker%  binop1(instr="shrl    %cl, %eax")
596*795d594fSAndroid Build Coastguard Worker
597*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_2addr():
598*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="shrl    %cl, %eax")
599*795d594fSAndroid Build Coastguard Worker
600*795d594fSAndroid Build Coastguard Worker%def op_ushr_int_lit8():
601*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="shrl    %cl, %eax")
602*795d594fSAndroid Build Coastguard Worker
603*795d594fSAndroid Build Coastguard Worker%def op_ushr_long():
604*795d594fSAndroid Build Coastguard Worker%  binop1(instr="shrq    %cl, %rax", wide="1")
605*795d594fSAndroid Build Coastguard Worker
606*795d594fSAndroid Build Coastguard Worker%def op_ushr_long_2addr():
607*795d594fSAndroid Build Coastguard Worker%  shop2addr(instr="shrq    %cl, %rax", wide="1")
608*795d594fSAndroid Build Coastguard Worker
609*795d594fSAndroid Build Coastguard Worker%def op_xor_int():
610*795d594fSAndroid Build Coastguard Worker%  binop(instr="xorl")
611*795d594fSAndroid Build Coastguard Worker
612*795d594fSAndroid Build Coastguard Worker%def op_xor_int_2addr():
613*795d594fSAndroid Build Coastguard Worker%  binop2addr(instr="xorl")
614*795d594fSAndroid Build Coastguard Worker
615*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit16():
616*795d594fSAndroid Build Coastguard Worker%  binopLit16(instr="xorl    %ecx, %eax")
617*795d594fSAndroid Build Coastguard Worker
618*795d594fSAndroid Build Coastguard Worker%def op_xor_int_lit8():
619*795d594fSAndroid Build Coastguard Worker%  binopLit8(instr="xorl    %ecx, %eax")
620*795d594fSAndroid Build Coastguard Worker
621*795d594fSAndroid Build Coastguard Worker%def op_xor_long():
622*795d594fSAndroid Build Coastguard Worker%  binopWide(instr="xorq")
623*795d594fSAndroid Build Coastguard Worker
624*795d594fSAndroid Build Coastguard Worker%def op_xor_long_2addr():
625*795d594fSAndroid Build Coastguard Worker%  binopWide2addr(instr="xorq")
626