You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(4) |
2
(2) |
|
3
(1) |
4
(1) |
5
|
6
|
7
|
8
(1) |
9
(1) |
|
10
(4) |
11
(1) |
12
(2) |
13
(2) |
14
(3) |
15
(2) |
16
(2) |
|
17
|
18
(1) |
19
(5) |
20
|
21
|
22
(8) |
23
(4) |
|
24
(1) |
25
|
26
(3) |
27
(8) |
28
(4) |
29
(4) |
30
(1) |
|
From: Ivo R. <ir...@so...> - 2017-09-28 21:40:04
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=8cdeee4ebba9cbcc267cf6b2a9464ba1de958680 commit 8cdeee4ebba9cbcc267cf6b2a9464ba1de958680 Author: Ivo Raisr <iv...@iv...> Date: Thu Sep 28 07:39:12 2017 +0200 Minor refactoring for VEX register allocator v3. No functional change. Diff: --- VEX/priv/host_generic_reg_alloc3.c | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c index 5b2a9f2..929dee5 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -140,6 +140,20 @@ typedef #define IS_VALID_VREGNO(v) ((v) >= 0 && (v) < n_vregs) #define IS_VALID_RREGNO(r) ((r) >= 0 && (r) < n_rregs) +#define FREE_VREG(v) \ + do { \ + (v)->disp = Unallocated; \ + (v)->rreg = INVALID_HREG; \ + } while (0) + +#define FREE_RREG(r) \ + do { \ + (r)->disp = Free; \ + (r)->vreg = INVALID_HREG; \ + (r)->eq_spill_slot = False; \ + } while (0) + + /* Compute the index of the highest and lowest 1 in a ULong, respectively. Results are undefined if the argument is zero. Don't pass it zero :) */ static inline UInt ULong__maxIndex ( ULong w64 ) { @@ -266,11 +280,9 @@ static inline void mark_vreg_spilled( HReg rreg = vreg_state[v_idx].rreg; UInt r_idx = hregIndex(rreg); - vreg_state[v_idx].disp = Spilled; - vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - rreg_state[r_idx].eq_spill_slot = False; + vreg_state[v_idx].disp = Spilled; + vreg_state[v_idx].rreg = INVALID_HREG; + FREE_RREG(&rreg_state[r_idx]); } /* Spills a vreg assigned to some rreg. @@ -891,8 +903,7 @@ HInstrArray* doRegisterAllocation_v3( HReg rreg = vreg_state[vs_idx].rreg; vreg_state[vd_idx].disp = Assigned; vreg_state[vd_idx].rreg = rreg; - vreg_state[vs_idx].disp = Unallocated; - vreg_state[vs_idx].rreg = INVALID_HREG; + FREE_VREG(&vreg_state[vs_idx]); UInt r_idx = hregIndex(rreg); vassert(rreg_state[r_idx].disp == Bound); @@ -913,11 +924,8 @@ HInstrArray* doRegisterAllocation_v3( contained dead code (but VEX iropt passes are pretty good at eliminating it) or the VEX backend generated dead code. */ if (vreg_state[vd_idx].dead_before <= (Short) ii + 1) { - vreg_state[vd_idx].disp = Unallocated; - vreg_state[vd_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - rreg_state[r_idx].eq_spill_slot = False; + FREE_VREG(&vreg_state[vd_idx]); + FREE_RREG(&rreg_state[r_idx]); } /* Move on to the next instruction. We skip the post-instruction @@ -1000,9 +1008,7 @@ HInstrArray* doRegisterAllocation_v3( rreg_state[r_free_idx].disp = Bound; rreg_state[r_free_idx].vreg = vreg; rreg_state[r_free_idx].eq_spill_slot = rreg->eq_spill_slot; - rreg->disp = Free; - rreg->vreg = INVALID_HREG; - rreg->eq_spill_slot = False; + FREE_RREG(rreg); } break; } @@ -1187,9 +1193,7 @@ HInstrArray* doRegisterAllocation_v3( if (rreg_lrs->lrs_used > 0) { /* Consider "dead before" the next instruction. */ if (rreg_lrs->lr_current->dead_before <= (Short) ii + 1) { - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - rreg_state[r_idx].eq_spill_slot = False; + FREE_RREG(&rreg_state[r_idx]); if (rreg_lrs->lr_current_idx < rreg_lrs->lrs_used - 1) { rreg_lrs->lr_current_idx += 1; rreg_lrs->lr_current @@ -1202,11 +1206,8 @@ HInstrArray* doRegisterAllocation_v3( UInt v_idx = hregIndex(rreg->vreg); /* Consider "dead before" the next instruction. */ if (vreg_state[v_idx].dead_before <= (Short) ii + 1) { - vreg_state[v_idx].disp = Unallocated; - vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - rreg_state[r_idx].eq_spill_slot = False; + FREE_VREG(&vreg_state[v_idx]); + FREE_RREG(&rreg_state[r_idx]); } break; } |
|
From: Ivo R. <ir...@so...> - 2017-09-28 20:53:53
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1379be41279c4d87a514644a50a0878c5f4e4edd commit 1379be41279c4d87a514644a50a0878c5f4e4edd Author: Ivo Raisr <iv...@iv...> Date: Thu Sep 28 21:06:25 2017 +0200 Fix missing breaks in merge_vreg_states(). Diff: --- VEX/priv/host_generic_reg_alloc3.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c index 92b44f8..899fefe 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -1541,7 +1541,7 @@ static void merge_vreg_states(RegAllocChunk* chunk, case Unallocated: /* Good. Nothing to do. */ break; - case Assigned: + case Assigned: /* fall through */ case Spilled: /* Should be dead by now. */ vassert(v2_src_state->dead_before <= chunk->next->ii_total_start); @@ -1603,6 +1603,7 @@ static void merge_vreg_states(RegAllocChunk* chunk, case Unallocated: vpanic("Logic error during register allocator state merge " " (Spilled/Unallocated)."); + break; case Assigned: /* Generate spill. */ vpanic("Spill not implemented, yet."); @@ -1615,9 +1616,11 @@ static void merge_vreg_states(RegAllocChunk* chunk, spill to v1_dst_state->spill_slot. */ vpanic("Spilled/Spilled reload not implemented, yet."); } + break; default: vassert(0); } + break; default: vassert(0); |
|
From: Ivo R. <ir...@so...> - 2017-09-28 20:51:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=ffdc4e643021bcdb12f4c5bbfd9599958f7744d6 commit ffdc4e643021bcdb12f4c5bbfd9599958f7744d6 Author: Ivo Raisr <iv...@iv...> Date: Thu Sep 28 09:23:27 2017 +0200 Cherry pick 8cdeee4ebba9cbcc267cf6b2a9464ba1de958680 from master. Minor refactoring for VEX register allocator v3. No functional change. Diff: --- VEX/priv/host_generic_reg_alloc3.c | 64 +++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c index 889766d..92b44f8 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -183,6 +183,19 @@ typedef #define IS_VALID_VREGNO(v) ((v) >= 0 && (v) < state->n_vregs) #define IS_VALID_RREGNO(r) ((r) >= 0 && (r) < state->n_rregs) +#define FREE_VREG(v) \ + do { \ + (v)->disp = Unallocated; \ + (v)->rreg = INVALID_HREG; \ + } while (0) + +#define FREE_RREG(r) \ + do { \ + (r)->disp = Free; \ + (r)->vreg = INVALID_HREG; \ + (r)->eq_spill_slot = False; \ + } while (0) + /* Represents register allocator state corresponding to one contiguous chunk of instructions. The chunk either continues with If-Then-Else legs or simply ends. */ @@ -450,11 +463,9 @@ static inline void mark_vreg_spilled(UInt v_idx, RegAllocState* state) HReg rreg = state->vregs[v_idx].rreg; UInt r_idx = hregIndex(rreg); - state->vregs[v_idx].disp = Spilled; - state->vregs[v_idx].rreg = INVALID_HREG; - state->rregs[r_idx].disp = Free; - state->rregs[r_idx].vreg = INVALID_HREG; - state->rregs[r_idx].eq_spill_slot = False; + state->vregs[v_idx].disp = Spilled; + state->vregs[v_idx].rreg = INVALID_HREG; + FREE_RREG(&state->rregs[r_idx]); } /* Spills a vreg assigned to some rreg. @@ -1173,8 +1184,7 @@ static void stage4_chunk(RegAllocChunk* chunk, RegAllocState* state, HReg rreg = state->vregs[vs_idx].rreg; state->vregs[vd_idx].disp = Assigned; state->vregs[vd_idx].rreg = rreg; - state->vregs[vs_idx].disp = Unallocated; - state->vregs[vs_idx].rreg = INVALID_HREG; + FREE_VREG(&state->vregs[vs_idx]); UInt r_idx = hregIndex(rreg); vassert(state->rregs[r_idx].disp == Bound); @@ -1196,11 +1206,8 @@ static void stage4_chunk(RegAllocChunk* chunk, RegAllocState* state, contained dead code (although VEX iropt passes are pretty good at eliminating it) or the VEX backend generated dead code. */ if (state->vregs[vd_idx].dead_before <= INSTRNO_TOTAL + 1) { - state->vregs[vd_idx].disp = Unallocated; - state->vregs[vd_idx].rreg = INVALID_HREG; - state->rregs[r_idx].disp = Free; - state->rregs[r_idx].vreg = INVALID_HREG; - state->rregs[r_idx].eq_spill_slot = False; + FREE_VREG(&state->vregs[vd_idx]); + FREE_RREG(&state->rregs[r_idx]); } /* Move on to the next instruction. We skip the post-instruction @@ -1279,12 +1286,10 @@ static void stage4_chunk(RegAllocChunk* chunk, RegAllocState* state, /* Update the register allocator state. */ vassert(state->vregs[v_idx].disp == Assigned); state->vregs[v_idx].rreg = con->univ->regs[r_free_idx]; - state->rregs[r_free_idx].disp = Bound; - state->rregs[r_free_idx].vreg = vreg; + state->rregs[r_free_idx].disp = Bound; + state->rregs[r_free_idx].vreg = vreg; state->rregs[r_free_idx].eq_spill_slot = rreg->eq_spill_slot; - rreg->disp = Free; - rreg->vreg = INVALID_HREG; - rreg->eq_spill_slot = False; + FREE_RREG(rreg); } break; } @@ -1472,9 +1477,7 @@ static void stage4_chunk(RegAllocChunk* chunk, RegAllocState* state, if (rreg_lrs->lrs_used > 0) { /* Consider "dead before" the next instruction. */ if (rreg_lrs->lr_current->dead_before <= ii_chunk + 1) { - state->rregs[r_idx].disp = Free; - state->rregs[r_idx].vreg = INVALID_HREG; - state->rregs[r_idx].eq_spill_slot = False; + FREE_RREG(&state->rregs[r_idx]); if (rreg_lrs->lr_current_idx < rreg_lrs->lrs_used - 1) { rreg_lrs->lr_current_idx += 1; rreg_lrs->lr_current @@ -1487,11 +1490,8 @@ static void stage4_chunk(RegAllocChunk* chunk, RegAllocState* state, UInt v_idx = hregIndex(rreg->vreg); /* Consider "dead before" the next instruction. */ if (state->vregs[v_idx].dead_before <= INSTRNO_TOTAL + 1) { - state->vregs[v_idx].disp = Unallocated; - state->vregs[v_idx].rreg = INVALID_HREG; - state->rregs[r_idx].disp = Free; - state->rregs[r_idx].vreg = INVALID_HREG; - state->rregs[r_idx].eq_spill_slot = False; + FREE_VREG(&state->vregs[v_idx]); + FREE_RREG(&state->rregs[r_idx]); } break; } @@ -1547,12 +1547,8 @@ static void merge_vreg_states(RegAllocChunk* chunk, vassert(v2_src_state->dead_before <= chunk->next->ii_total_start); HReg rreg2 = v2_src_state->rreg; - UInt r_idx = hregIndex(rreg2); - v2_src_state->disp = Unallocated; - v2_src_state->rreg = INVALID_HREG; - state2->rregs[r_idx].disp = Free; - state2->rregs[r_idx].vreg = INVALID_HREG; - state2->rregs[r_idx].eq_spill_slot = False; + FREE_VREG(v2_src_state); + FREE_RREG(&state2->rregs[hregIndex(rreg2)]); break; default: vassert(0); @@ -1577,10 +1573,8 @@ static void merge_vreg_states(RegAllocChunk* chunk, emit_instr(outOfLine, move, depth + 1, con, "move"); } - v1_src_state->disp = Unallocated; - v1_src_state->rreg = INVALID_HREG; - v2_src_state->disp = Unallocated; - v2_src_state->rreg = INVALID_HREG; + FREE_VREG(v1_src_state); + FREE_VREG(v2_src_state); v1_dst_state->disp = Assigned; v1_dst_state->rreg = rreg1; v2_dst_state->disp = Assigned; |
|
From: Petar J. <pe...@so...> - 2017-09-28 19:54:38
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=eb18bd1b447061ba42e6c7c24210675f2c8557ac commit eb18bd1b447061ba42e6c7c24210675f2c8557ac Author: Petar Jovanovic <mip...@gm...> Date: Thu Sep 28 19:29:51 2017 +0200 mips: optimize multiplication Iops Optimize and refactor some of mul* Iop code in VEX/priv/host_mips_. Patch from Aleksandar Rikalo. Diff: --- VEX/priv/host_mips_defs.c | 160 ++++++++++++++++++++++++++++++++-------------- VEX/priv/host_mips_defs.h | 21 +++++- VEX/priv/host_mips_isel.c | 78 ++++++++++------------ VEX/pub/libvex.h | 3 + 4 files changed, 167 insertions(+), 95 deletions(-) diff --git a/VEX/priv/host_mips_defs.c b/VEX/priv/host_mips_defs.c index 9a6993e..66c226d 100644 --- a/VEX/priv/host_mips_defs.c +++ b/VEX/priv/host_mips_defs.c @@ -811,21 +811,40 @@ MIPSInstr *MIPSInstr_Cmp(Bool syned, Bool sz32, HReg dst, HReg srcL, HReg srcR, return i; } -/* multiply */ -MIPSInstr *MIPSInstr_Mul(Bool syned, Bool wid, Bool sz32, HReg dst, HReg srcL, - HReg srcR) +/* mul */ +MIPSInstr *MIPSInstr_Mul(HReg dst, HReg srcL, HReg srcR) { MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr)); i->tag = Min_Mul; - i->Min.Mul.syned = syned; - i->Min.Mul.widening = wid; /* widen=True else False */ - i->Min.Mul.sz32 = sz32; /* True = 32 bits */ i->Min.Mul.dst = dst; i->Min.Mul.srcL = srcL; i->Min.Mul.srcR = srcR; return i; } +/* mult, multu / dmult, dmultu */ +MIPSInstr *MIPSInstr_Mult(Bool syned, HReg srcL, HReg srcR) +{ + MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr)); + i->tag = Min_Mult; + i->Min.Mult.syned = syned; + i->Min.Mult.srcL = srcL; + i->Min.Mult.srcR = srcR; + return i; +} + +/* ext / dext, dextm, dextu */ +MIPSInstr *MIPSInstr_Ext(HReg dst, HReg src, UInt pos, UInt size) +{ + MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr)); + i->tag = Min_Ext; + i->Min.Ext.dst = dst; + i->Min.Ext.src = src; + i->Min.Ext.pos = pos; + i->Min.Ext.size = size; + return i; +} + /* msub */ MIPSInstr *MIPSInstr_Msub(Bool syned, HReg srcL, HReg srcR) { @@ -1228,26 +1247,35 @@ void ppMIPSInstr(const MIPSInstr * i, Bool mode64) return; } case Min_Mul: { - switch (i->Min.Mul.widening) { - case False: - vex_printf("mul "); - ppHRegMIPS(i->Min.Mul.dst, mode64); - vex_printf(", "); - ppHRegMIPS(i->Min.Mul.srcL, mode64); - vex_printf(", "); - ppHRegMIPS(i->Min.Mul.srcR, mode64); - return; - case True: - vex_printf("%s%s ", i->Min.Mul.sz32 ? "mult" : "dmult", - i->Min.Mul.syned ? "" : "u"); - ppHRegMIPS(i->Min.Mul.dst, mode64); - vex_printf(", "); - ppHRegMIPS(i->Min.Mul.srcL, mode64); - vex_printf(", "); - ppHRegMIPS(i->Min.Mul.srcR, mode64); - return; - } - break; + vex_printf("mul "); + ppHRegMIPS(i->Min.Mul.dst, mode64); + vex_printf(", "); + ppHRegMIPS(i->Min.Mul.srcL, mode64); + vex_printf(", "); + ppHRegMIPS(i->Min.Mul.srcR, mode64); + return; + } + case Min_Mult: { + vex_printf("%s%s ", mode64 ? "dmult" : "mult", + i->Min.Mult.syned ? "" : "u"); + ppHRegMIPS(i->Min.Mult.srcL, mode64); + vex_printf(", "); + ppHRegMIPS(i->Min.Mult.srcR, mode64); + return; + } + case Min_Ext: { + vassert(mode64); + vassert(i->Min.Ext.pos < 32); + vassert(i->Min.Ext.size > 0); + vassert(i->Min.Ext.size <= 32); + vassert(i->Min.Ext.size + i->Min.Ext.pos > 0); + vassert(i->Min.Ext.size + i->Min.Ext.pos <= 63); + vex_printf("dext "); + ppHRegMIPS(i->Min.Ext.dst, mode64); + vex_printf(", "); + ppHRegMIPS(i->Min.Ext.src, mode64); + vex_printf(", %u, %u", i->Min.Ext.pos, i->Min.Ext.size); + return; } case Min_Mthi: { vex_printf("mthi "); @@ -1597,6 +1625,18 @@ void getRegUsage_MIPSInstr(HRegUsage * u, const MIPSInstr * i, Bool mode64) addHRegUse(u, HRmWrite, i->Min.Mul.dst); addHRegUse(u, HRmRead, i->Min.Mul.srcL); addHRegUse(u, HRmRead, i->Min.Mul.srcR); + addHRegUse(u, HRmWrite, hregMIPS_HI(mode64)); + addHRegUse(u, HRmWrite, hregMIPS_LO(mode64)); + return; + case Min_Mult: + addHRegUse(u, HRmRead, i->Min.Mult.srcL); + addHRegUse(u, HRmRead, i->Min.Mult.srcR); + addHRegUse(u, HRmWrite, hregMIPS_HI(mode64)); + addHRegUse(u, HRmWrite, hregMIPS_LO(mode64)); + return; + case Min_Ext: + addHRegUse(u, HRmWrite, i->Min.Ext.dst); + addHRegUse(u, HRmRead, i->Min.Ext.src); return; case Min_Mthi: case Min_Mtlo: @@ -1817,6 +1857,14 @@ void mapRegs_MIPSInstr(HRegRemap * m, MIPSInstr * i, Bool mode64) mapReg(m, &i->Min.Mul.srcL); mapReg(m, &i->Min.Mul.srcR); return; + case Min_Mult: + mapReg(m, &i->Min.Mult.srcL); + mapReg(m, &i->Min.Mult.srcR); + return; + case Min_Ext: + mapReg(m, &i->Min.Ext.src); + mapReg(m, &i->Min.Ext.dst); + return; case Min_Mthi: case Min_Mtlo: mapReg(m, &i->Min.MtHL.src); @@ -2808,38 +2856,52 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, } case Min_Mul: { - Bool syned = i->Min.Mul.syned; - Bool widening = i->Min.Mul.widening; - Bool sz32 = i->Min.Mul.sz32; UInt r_srcL = iregNo(i->Min.Mul.srcL, mode64); UInt r_srcR = iregNo(i->Min.Mul.srcR, mode64); UInt r_dst = iregNo(i->Min.Mul.dst, mode64); - if (widening) { - if (sz32) { - if (syned) - /* mult */ - p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 24); - else - /* multu */ - p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 25); - } else { - if (syned) /* DMULT r_dst,r_srcL,r_srcR */ - p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 28); - else /* DMULTU r_dst,r_srcL,r_srcR */ - p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 29); - } + /* mul r_dst, r_srcL, r_srcR */ + p = mkFormR(p, 28, r_srcL, r_srcR, r_dst, 0, 2); + goto done; + } + + case Min_Mult: { + Bool syned = i->Min.Mult.syned; + UInt r_srcL = iregNo(i->Min.Mult.srcL, mode64); + UInt r_srcR = iregNo(i->Min.Mult.srcR, mode64); + if (mode64) { + if (syned) + /* dmult r_srcL, r_srcR */ + p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 28); + else + /* dmultu r_srcL, r_srcR */ + p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 29); } else { - if (sz32) - /* mul */ - p = mkFormR(p, 28, r_srcL, r_srcR, r_dst, 0, 2); - else if (mode64 && !sz32) - p = mkFormR(p, 28, r_srcL, r_srcR, r_dst, 0, 2); + if (syned) + /* mult r_srcL, r_srcR */ + p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 24); else - goto bad; + /* multu r_srcL, r_srcR */ + p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 25); } goto done; } + case Min_Ext: { + UInt r_src = iregNo(i->Min.Ext.src, mode64); + UInt r_dst = iregNo(i->Min.Ext.dst, mode64); + /* For now, only DEXT is implemented. */ + vassert(mode64); + vassert(i->Min.Ext.pos < 32); + vassert(i->Min.Ext.size > 0); + vassert(i->Min.Ext.size <= 32); + vassert(i->Min.Ext.size + i->Min.Ext.pos > 0); + vassert(i->Min.Ext.size + i->Min.Ext.pos <= 63); + /* DEXT r_dst, r_src, pos, size */ + p = mkFormR(p, 0x1F, r_src, r_dst, + i->Min.Ext.size - 1, i->Min.Ext.pos, 3); + goto done; + } + case Min_Macc: { Bool syned = i->Min.Macc.syned; UInt r_srcL = iregNo(i->Min.Macc.srcL, mode64); diff --git a/VEX/priv/host_mips_defs.h b/VEX/priv/host_mips_defs.h index a4c0e78..be1e3a8 100644 --- a/VEX/priv/host_mips_defs.h +++ b/VEX/priv/host_mips_defs.h @@ -276,10 +276,12 @@ typedef enum { Min_Alu, /* word add/sub/and/or/xor/nor/others? */ Min_Shft, /* word sll/srl/sra */ Min_Unary, /* clo, clz, nop, neg */ + Min_Ext, /* ext / dext, dextm, dextu */ Min_Cmp, /* word compare (fake insn) */ - Min_Mul, /* widening/non-widening multiply */ + Min_Mul, /* non-widening, 32-bit, signed multiply */ + Min_Mult, /* widening multiply */ Min_Div, /* div */ Min_Call, /* call to address in register */ @@ -415,6 +417,13 @@ typedef struct { HReg dst; HReg src; } Unary; + /* Bit extract */ + struct { + HReg dst; + HReg src; + UInt pos; + UInt size; + } Ext; /* Word compare. Fake instruction, used for basic block ending */ struct { Bool syned; @@ -434,6 +443,11 @@ typedef struct { HReg srcR; } Mul; struct { + Bool syned; /* signed/unsigned */ + HReg srcL; + HReg srcR; + } Mult; + struct { Bool syned; /* signed/unsigned - meaningless if widenind = False */ Bool sz32; HReg srcL; @@ -615,10 +629,11 @@ extern MIPSInstr *MIPSInstr_LI(HReg, ULong); extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *); extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *); extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src); +extern MIPSInstr *MIPSInstr_Ext(HReg, HReg, UInt, UInt); extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode); -extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg, - HReg, HReg); +extern MIPSInstr *MIPSInstr_Mul(HReg, HReg, HReg); +extern MIPSInstr *MIPSInstr_Mult(Bool, HReg, HReg); extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg); extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg); extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg); diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index deb33f2..711af61 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -55,6 +55,9 @@ static Bool mode64 = False; /* Host CPU has FPU and 32 dbl. prec. FP registers. */ static Bool fp_mode64 = False; +/* Host hwcaps */ +static UInt hwcaps_host = 0; + /* GPR register class for mips32/64 */ #define HRcGPR(_mode64) ((_mode64) ? HRcInt64 : HRcInt32) @@ -1058,52 +1061,46 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) return r_dst; } - if (e->Iex.Binop.op == Iop_Mul32 || e->Iex.Binop.op == Iop_Mul64) { - Bool sz32 = (e->Iex.Binop.op == Iop_Mul32); + if (e->Iex.Binop.op == Iop_Mul32) { HReg r_dst = newVRegI(env); HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); - addInstr(env, MIPSInstr_Mul(False/*Unsigned or Signed */ , - False /*widen */ , - sz32 /*32bit or 64bit */, - r_dst, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Mul(r_dst, r_srcL, r_srcR)); return r_dst; } - if (e->Iex.Binop.op == Iop_MullU32 || e->Iex.Binop.op == Iop_MullS32) { + if (e->Iex.Binop.op == Iop_Mul64 || + e->Iex.Binop.op == Iop_MullS32) { + vassert(mode64); HReg r_dst = newVRegI(env); - HReg tHi = newVRegI(env); - HReg tLo = newVRegI(env); - HReg tLo_1 = newVRegI(env); - HReg tHi_1 = newVRegI(env); - HReg mask = newVRegI(env); - - Bool syned = toBool(e->Iex.Binop.op == Iop_MullS32); - Bool size = toBool(e->Iex.Binop.op == Iop_MullS32) - || toBool(e->Iex.Binop.op == Iop_MullU32); HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); - addInstr(env, MIPSInstr_Mul(syned /*Unsigned or Signed */ , - True /*widen */ , - size /*32bit or 64bit mul */ , - r_dst, r_srcL, r_srcR)); - - addInstr(env, MIPSInstr_Mfhi(tHi)); - addInstr(env, MIPSInstr_Mflo(tLo)); - - addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tHi_1, - tHi, MIPSRH_Imm(False, 32))); - - addInstr(env, MIPSInstr_LI(mask, 0xffffffff)); - addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo, - MIPSRH_Reg(mask))); - - addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1, - MIPSRH_Reg(tLo_1))); - + addInstr(env, MIPSInstr_Mult(True, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Mflo(r_dst)); return r_dst; } + if (e->Iex.Binop.op == Iop_MullU32) { + vassert(mode64); + HReg r_tmpL = newVRegI(env); + HReg r_tmpR = newVRegI(env); + HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); + HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); + if (VEX_MIPS_CPU_HAS_MIPS64R2(hwcaps_host)) { + addInstr(env, MIPSInstr_Ext(r_tmpL, r_srcL, 0, 32)); + addInstr(env, MIPSInstr_Ext(r_tmpR, r_srcR, 0, 32)); + } else { + addInstr(env, MIPSInstr_LI(r_tmpL, 0xFFFFFFFF)); + addInstr(env, MIPSInstr_Alu(Malu_AND, r_tmpR, r_srcR, + MIPSRH_Reg(r_tmpL))); + addInstr(env, MIPSInstr_Alu(Malu_AND, r_tmpL, r_srcL, + MIPSRH_Reg(r_tmpL))); + } + addInstr(env, MIPSInstr_Mult(False, r_tmpL, r_tmpR)); + addInstr(env, MIPSInstr_Mflo(r_tmpR)); + return r_tmpR; + } + if (e->Iex.Binop.op == Iop_CmpF64) { HReg r_srcL, r_srcR; if (mode64) { @@ -2198,11 +2195,9 @@ static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, HReg tLo = newVRegI(env); HReg tHi = newVRegI(env); Bool syned = toBool(e->Iex.Binop.op == Iop_MullS64); - HReg r_dst = newVRegI(env); HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); - addInstr(env, MIPSInstr_Mul(syned, True, False /*64bit mul */ , - r_dst, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Mult(syned, r_srcL, r_srcR)); addInstr(env, MIPSInstr_Mfhi(tHi)); addInstr(env, MIPSInstr_Mflo(tLo)); *rHi = tHi; @@ -2411,14 +2406,10 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e) case Iop_MullS32: { HReg tLo = newVRegI(env); HReg tHi = newVRegI(env); - HReg r_dst = newVRegI(env); Bool syned = toBool(op_binop == Iop_MullS32); HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); - - addInstr(env, MIPSInstr_Mul(syned /*Unsigned or Signed */, - True /*widen */ , True, - r_dst, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Mult(syned, r_srcL, r_srcR)); addInstr(env, MIPSInstr_Mfhi(tHi)); addInstr(env, MIPSInstr_Mflo(tLo)); *rHi = tHi; @@ -4155,9 +4146,10 @@ HInstrArray *iselSB_MIPS ( const IRSB* bb, Int i, j; HReg hreg, hregHI; ISelEnv* env; - UInt hwcaps_host = archinfo_host->hwcaps; MIPSAMode *amCounter, *amFailAddr; + hwcaps_host = archinfo_host->hwcaps; + /* sanity ... */ vassert(arch_host == VexArchMIPS32 || arch_host == VexArchMIPS64); vassert(VEX_PRID_COMP_MIPS == VEX_MIPS_COMP_ID(hwcaps_host) diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 6f55ec9..8ae3e36 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -246,6 +246,9 @@ typedef /* Check if the processor supports MIPS32R2. */ #define VEX_MIPS_CPU_HAS_MIPS32R2(x) (VEX_MIPS_EX_INFO(x) & \ VEX_MIPS_CPU_ISA_M32R2) +/* Check if the processor supports MIPS64R2. */ +#define VEX_MIPS_CPU_HAS_MIPS64R2(x) (VEX_MIPS_EX_INFO(x) & \ + VEX_MIPS_CPU_ISA_M64R2) /* Check if the processor supports DSP ASE Rev 2. */ #define VEX_MIPS_PROC_DSP2(x) ((VEX_MIPS_COMP_ID(x) == VEX_PRID_COMP_MIPS) && \ (VEX_MIPS_PROC_ID(x) == VEX_PRID_IMP_74K)) |