You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
7.2 KiB
251 lines
7.2 KiB
%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 */
|
|
movzbq 3(rPC), %rcx # ecx<- CC
|
|
movzbq 2(rPC), %rax # eax<- BB
|
|
GET_VREG_XMM${suff} %xmm0, %rax
|
|
xor %eax, %eax
|
|
ucomis${suff} VREG_ADDRESS(%rcx), %xmm0
|
|
jp .L${opcode}_nan_is_${nanval}
|
|
je .L${opcode}_finish
|
|
jb .L${opcode}_less
|
|
.L${opcode}_nan_is_pos:
|
|
addb $$1, %al
|
|
jmp .L${opcode}_finish
|
|
.L${opcode}_nan_is_neg:
|
|
.L${opcode}_less:
|
|
movl $$-1, %eax
|
|
.L${opcode}_finish:
|
|
SET_VREG %eax, rINSTq
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
|
|
|
|
%def fpcvt(source_suffix="", dest_suffix="", wide=""):
|
|
/*
|
|
* Generic 32-bit FP conversion operation.
|
|
*/
|
|
/* unop vA, vB */
|
|
movl rINST, %ecx # rcx <- A+
|
|
sarl $$4, rINST # rINST <- B
|
|
andb $$0xf, %cl # ecx <- A
|
|
cvts${source_suffix}2s${dest_suffix} VREG_ADDRESS(rINSTq), %xmm0
|
|
.if $wide
|
|
SET_VREG_XMMd %xmm0, %rcx
|
|
CLEAR_WIDE_REF %rcx
|
|
.else
|
|
SET_VREG_XMMs %xmm0, %rcx
|
|
CLEAR_REF %rcx
|
|
.endif
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
|
|
|
|
%def sseBinop(instr="", suff=""):
|
|
movzbq 2(rPC), %rcx # ecx <- BB
|
|
movzbq 3(rPC), %rax # eax <- CC
|
|
GET_VREG_XMM${suff} %xmm0, %rcx # %xmm0 <- 1st src
|
|
#ifdef MTERP_USE_AVX
|
|
v${instr}${suff} VREG_ADDRESS(%rax), %xmm0, %xmm0
|
|
SET_VREG_XMM${suff} %xmm0, rINSTq # vAA <- %xmm0
|
|
vpxor %xmm0, %xmm0, %xmm0
|
|
vmovs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
|
|
#else
|
|
${instr}${suff} VREG_ADDRESS(%rax), %xmm0
|
|
SET_VREG_XMM${suff} %xmm0, rINSTq # vAA <- %xmm0
|
|
pxor %xmm0, %xmm0
|
|
movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
|
|
#endif
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
|
|
|
|
%def sseBinop2Addr(instr="", suff=""):
|
|
movl rINST, %ecx # ecx <- A+
|
|
andl $$0xf, %ecx # ecx <- A
|
|
GET_VREG_XMM${suff} %xmm0, %rcx # %xmm0 <- 1st src
|
|
sarl $$4, rINST # rINST<- B
|
|
#ifdef MTERP_USE_AVX
|
|
v${instr}${suff} VREG_ADDRESS(rINSTq), %xmm0, %xmm0
|
|
SET_VREG_XMM${suff} %xmm0, %rcx # vAA <- %xmm0
|
|
vpxor %xmm0, %xmm0, %xmm0
|
|
vmovs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # clear ref
|
|
#else
|
|
${instr}${suff} VREG_ADDRESS(rINSTq), %xmm0
|
|
SET_VREG_XMM${suff} %xmm0, %rcx # vAA <- %xmm0
|
|
pxor %xmm0, %xmm0
|
|
movs${suff} %xmm0, VREG_REF_ADDRESS(rINSTq) # 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(source_suffix="d", dest_suffix="s", wide="0")
|
|
|
|
%def op_double_to_int():
|
|
% cvtfp_int(fp_suffix="d", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
|
|
|
|
%def op_double_to_long():
|
|
% cvtfp_int(fp_suffix="d", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
|
|
|
|
%def op_float_to_double():
|
|
% fpcvt(source_suffix="s", dest_suffix="d", wide="1")
|
|
|
|
%def op_float_to_int():
|
|
% cvtfp_int(fp_suffix="s", i_suffix="l", max_const="$0x7fffffff", result_reg="%eax", wide="0")
|
|
|
|
%def op_float_to_long():
|
|
% cvtfp_int(fp_suffix="s", i_suffix="q", max_const="$0x7fffffffffffffff", result_reg="%rax", wide="1")
|
|
|
|
%def op_int_to_double():
|
|
% fpcvt(source_suffix="i", dest_suffix="dl", wide="1")
|
|
|
|
%def op_int_to_float():
|
|
% fpcvt(source_suffix="i", dest_suffix="sl", wide="0")
|
|
|
|
%def op_long_to_double():
|
|
% fpcvt(source_suffix="i", dest_suffix="dq", wide="1")
|
|
|
|
%def op_long_to_float():
|
|
% fpcvt(source_suffix="i", dest_suffix="sq", wide="0")
|
|
|
|
%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():
|
|
% unop(preinstr=" movq $0x8000000000000000, %rsi", instr=" xorq %rsi, %rax", wide="1")
|
|
|
|
%def op_neg_float():
|
|
% unop(instr=" xorl $0x80000000, %eax")
|
|
|
|
%def op_rem_double():
|
|
/* rem_double vAA, vBB, vCC */
|
|
movzbq 3(rPC), %rcx # ecx <- BB
|
|
movzbq 2(rPC), %rax # eax <- CC
|
|
fldl VREG_ADDRESS(%rcx) # %st1 <- fp[vBB]
|
|
fldl VREG_ADDRESS(%rax) # %st0 <- fp[vCC]
|
|
1:
|
|
fprem
|
|
fstsw %ax
|
|
sahf
|
|
jp 1b
|
|
fstp %st(1)
|
|
fstpl VREG_ADDRESS(rINSTq) # fp[vAA] <- %st
|
|
CLEAR_WIDE_REF rINSTq
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
|
|
|
|
%def op_rem_double_2addr():
|
|
/* rem_double/2addr vA, vB */
|
|
movzbq rINSTbl, %rcx # ecx <- A+
|
|
sarl $$4, rINST # rINST <- B
|
|
fldl VREG_ADDRESS(rINSTq) # vB to fp stack
|
|
andb $$0xf, %cl # ecx <- A
|
|
fldl VREG_ADDRESS(%rcx) # vA to fp stack
|
|
1:
|
|
fprem
|
|
fstsw %ax
|
|
sahf
|
|
jp 1b
|
|
fstp %st(1)
|
|
fstpl VREG_ADDRESS(%rcx) # %st to vA
|
|
CLEAR_WIDE_REF %rcx
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
|
|
|
|
%def op_rem_float():
|
|
/* rem_float vAA, vBB, vCC */
|
|
movzbq 3(rPC), %rcx # ecx <- BB
|
|
movzbq 2(rPC), %rax # eax <- CC
|
|
flds VREG_ADDRESS(%rcx) # vBB to fp stack
|
|
flds VREG_ADDRESS(%rax) # vCC to fp stack
|
|
1:
|
|
fprem
|
|
fstsw %ax
|
|
sahf
|
|
jp 1b
|
|
fstp %st(1)
|
|
fstps VREG_ADDRESS(rINSTq) # %st to vAA
|
|
CLEAR_REF rINSTq
|
|
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
|
|
|
|
%def op_rem_float_2addr():
|
|
/* rem_float/2addr vA, vB */
|
|
movzbq rINSTbl, %rcx # ecx <- A+
|
|
sarl $$4, rINST # rINST <- B
|
|
flds VREG_ADDRESS(rINSTq) # vB to fp stack
|
|
andb $$0xf, %cl # ecx <- A
|
|
flds VREG_ADDRESS(%rcx) # vA to fp stack
|
|
1:
|
|
fprem
|
|
fstsw %ax
|
|
sahf
|
|
jp 1b
|
|
fstp %st(1)
|
|
fstps VREG_ADDRESS(%rcx) # %st to vA
|
|
CLEAR_REF %rcx
|
|
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")
|