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