|
Mark Wielaard |
1a6c01 |
From f730da53e59ab25c5b250d7730ead57b6f72fdcf Mon Sep 17 00:00:00 2001
|
|
Mark Wielaard |
1a6c01 |
From: Julian Seward <jseward@acm.org>
|
|
Mark Wielaard |
1a6c01 |
Date: Sun, 23 Dec 2018 21:03:08 +0100
|
|
Mark Wielaard |
1a6c01 |
Subject: [PATCH] Implement Iop_Sar64 in the x86 back end.
|
|
Mark Wielaard |
1a6c01 |
|
|
Mark Wielaard |
1a6c01 |
---
|
|
Mark Wielaard |
1a6c01 |
VEX/priv/host_x86_isel.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Mark Wielaard |
1a6c01 |
1 file changed, 50 insertions(+)
|
|
Mark Wielaard |
1a6c01 |
|
|
Mark Wielaard |
1a6c01 |
diff --git a/VEX/priv/host_x86_isel.c b/VEX/priv/host_x86_isel.c
|
|
Mark Wielaard |
1a6c01 |
index 45aafeb..9ca8a45 100644
|
|
Mark Wielaard |
1a6c01 |
--- a/VEX/priv/host_x86_isel.c
|
|
Mark Wielaard |
1a6c01 |
+++ b/VEX/priv/host_x86_isel.c
|
|
Mark Wielaard |
1a6c01 |
@@ -2380,6 +2380,56 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env,
|
|
Mark Wielaard |
1a6c01 |
return;
|
|
Mark Wielaard |
1a6c01 |
}
|
|
Mark Wielaard |
1a6c01 |
|
|
Mark Wielaard |
1a6c01 |
+ case Iop_Sar64: {
|
|
Mark Wielaard |
1a6c01 |
+ /* gcc -O2 does the following. I don't know how it works, but it
|
|
Mark Wielaard |
1a6c01 |
+ does work. Don't mess with it. This is hard to test because the
|
|
Mark Wielaard |
1a6c01 |
+ x86 front end doesn't create Iop_Sar64 for any x86 instruction,
|
|
Mark Wielaard |
1a6c01 |
+ so it's impossible to write a test program that feeds values
|
|
Mark Wielaard |
1a6c01 |
+ through Iop_Sar64 and prints their results. The implementation
|
|
Mark Wielaard |
1a6c01 |
+ here was tested by using psrlq on mmx registers -- that generates
|
|
Mark Wielaard |
1a6c01 |
+ Iop_Shr64 -- and temporarily hacking the front end to generate
|
|
Mark Wielaard |
1a6c01 |
+ Iop_Sar64 for that instruction instead.
|
|
Mark Wielaard |
1a6c01 |
+
|
|
Mark Wielaard |
1a6c01 |
+ movl %amount, %ecx
|
|
Mark Wielaard |
1a6c01 |
+ movl %srcHi, %r1
|
|
Mark Wielaard |
1a6c01 |
+ movl %srcLo, %r2
|
|
Mark Wielaard |
1a6c01 |
+
|
|
Mark Wielaard |
1a6c01 |
+ movl %r1, %r3
|
|
Mark Wielaard |
1a6c01 |
+ sarl %cl, %r3
|
|
Mark Wielaard |
1a6c01 |
+ movl %r2, %r4
|
|
Mark Wielaard |
1a6c01 |
+ shrdl %cl, %r1, %r4
|
|
Mark Wielaard |
1a6c01 |
+ movl %r3, %r2
|
|
Mark Wielaard |
1a6c01 |
+ sarl $31, %r2
|
|
Mark Wielaard |
1a6c01 |
+ andl $32, %ecx
|
|
Mark Wielaard |
1a6c01 |
+ cmovne %r3, %r4 // = resLo
|
|
Mark Wielaard |
1a6c01 |
+ cmovne %r2, %r3 // = resHi
|
|
Mark Wielaard |
1a6c01 |
+ */
|
|
Mark Wielaard |
1a6c01 |
+ HReg amount = iselIntExpr_R(env, e->Iex.Binop.arg2);
|
|
Mark Wielaard |
1a6c01 |
+ HReg srcHi = INVALID_HREG, srcLo = INVALID_HREG;
|
|
Mark Wielaard |
1a6c01 |
+ iselInt64Expr(&srcHi, &srcLo, env, e->Iex.Binop.arg1);
|
|
Mark Wielaard |
1a6c01 |
+ HReg r1 = newVRegI(env);
|
|
Mark Wielaard |
1a6c01 |
+ HReg r2 = newVRegI(env);
|
|
Mark Wielaard |
1a6c01 |
+ HReg r3 = newVRegI(env);
|
|
Mark Wielaard |
1a6c01 |
+ HReg r4 = newVRegI(env);
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(amount, hregX86_ECX()));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(srcHi, r1));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(srcLo, r2));
|
|
Mark Wielaard |
1a6c01 |
+
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(r1, r3));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_Sh32(Xsh_SAR, 0/*%cl*/, r3));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(r2, r4));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_Sh3232(Xsh_SHR, 0/*%cl*/, r1, r4));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, mk_iMOVsd_RR(r3, r2));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, r2));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(32),
|
|
Mark Wielaard |
1a6c01 |
+ hregX86_ECX()));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(r3), r4));
|
|
Mark Wielaard |
1a6c01 |
+ addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(r2), r3));
|
|
Mark Wielaard |
1a6c01 |
+ *rHi = r3;
|
|
Mark Wielaard |
1a6c01 |
+ *rLo = r4;
|
|
Mark Wielaard |
1a6c01 |
+ return;
|
|
Mark Wielaard |
1a6c01 |
+ }
|
|
Mark Wielaard |
1a6c01 |
+
|
|
Mark Wielaard |
1a6c01 |
/* F64 -> I64 */
|
|
Mark Wielaard |
1a6c01 |
/* Sigh, this is an almost exact copy of the F64 -> I32/I16
|
|
Mark Wielaard |
1a6c01 |
case. Unfortunately I see no easy way to avoid the
|
|
Mark Wielaard |
1a6c01 |
--
|
|
Mark Wielaard |
1a6c01 |
1.8.3.1
|
|
Mark Wielaard |
1a6c01 |
|