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
(9) |
2
(2) |
3
(9) |
4
(19) |
5
(4) |
6
(1) |
7
(6) |
|
8
(11) |
9
(30) |
10
(12) |
11
(25) |
12
(7) |
13
(5) |
14
|
|
15
(17) |
16
(15) |
17
(20) |
18
(17) |
19
(5) |
20
(4) |
21
|
|
22
|
23
|
24
|
25
|
26
|
27
(4) |
28
(15) |
|
29
(10) |
30
(9) |
31
(11) |
|
|
|
|
|
From: <sv...@va...> - 2011-05-02 18:58:04
|
Author: sewardj
Date: 2011-05-02 19:57:56 +0100 (Mon, 02 May 2011)
New Revision: 2140
Log:
Add a spec rule for V after SUB.
Modified:
trunk/priv/guest_arm_helpers.c
Modified: trunk/priv/guest_arm_helpers.c
===================================================================
--- trunk/priv/guest_arm_helpers.c 2011-05-02 07:21:04 UTC (rev 2139)
+++ trunk/priv/guest_arm_helpers.c 2011-05-02 18:57:56 UTC (rev 2140)
@@ -717,6 +717,25 @@
return cc_ndep;
}
+ if (isU32(cc_op, ARMG_CC_OP_SUB)) {
+ /* Thunk args are (argL, argR, unused) */
+ /* V after SUB
+ --> let res = argL - argR
+ in ((argL ^ argR) & (argL ^ res)) >> 31
+ --> ((argL ^ argR) & (argL ^ (argL - argR))) >> 31
+ */
+ IRExpr* argL = cc_dep1;
+ IRExpr* argR = cc_dep2;
+ return
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ binop(Iop_Xor32, argL, argR),
+ binop(Iop_Xor32, argL, binop(Iop_Sub32, argL, argR))
+ ),
+ mkU8(31)
+ );
+ }
+
if (isU32(cc_op, ARMG_CC_OP_SBB)) {
/* This happens occasionally in softfloat code, eg __divdf3+140 */
/* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */
|
|
From: <sv...@va...> - 2011-05-02 07:21:17
|
Author: sewardj
Date: 2011-05-02 08:21:04 +0100 (Mon, 02 May 2011)
New Revision: 2139
Log:
Split up armg_calculate_flags_nzcv into four functions that compute
the flags individually. This seems to be a net performance win,
because often only one or two of the flags computed by
armg_calculate_flags_nzcv, so time was wasted computing the other
ones.
Modified:
trunk/priv/guest_arm_helpers.c
Modified: trunk/priv/guest_arm_helpers.c
===================================================================
--- trunk/priv/guest_arm_helpers.c 2011-05-01 18:47:10 UTC (rev 2138)
+++ trunk/priv/guest_arm_helpers.c 2011-05-02 07:21:04 UTC (rev 2139)
@@ -51,59 +51,109 @@
*/
-
-/* generalised left-shifter */
-static inline UInt lshift ( UInt x, Int n )
+/* Calculate the N flag from the supplied thunk components, in the
+ least significant bit of the word. Returned bits 31:1 are zero. */
+static
+UInt armg_calculate_flag_n ( UInt cc_op, UInt cc_dep1,
+ UInt cc_dep2, UInt cc_dep3 )
{
- if (n >= 0)
- return x << n;
- else
- return x >> (-n);
+ switch (cc_op) {
+ case ARMG_CC_OP_COPY: {
+ /* (nzcv:28x0, unused, unused) */
+ UInt nf = (cc_dep1 >> ARMG_CC_SHIFT_N) & 1;
+ return nf;
+ }
+ case ARMG_CC_OP_ADD: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt res = argL + argR;
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_SUB: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt res = argL - argR;
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_ADC: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt res = argL + argR + oldC;
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_SBB: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt res = argL - argR - (oldC ^ 1);
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_LOGIC: {
+ /* (res, shco, oldV) */
+ UInt res = cc_dep1;
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_MUL: {
+ /* (res, unused, oldC:oldV) */
+ UInt res = cc_dep1;
+ UInt nf = res >> 31;
+ return nf;
+ }
+ case ARMG_CC_OP_MULL: {
+ /* (resLo32, resHi32, oldC:oldV) */
+ UInt resHi32 = cc_dep2;
+ UInt nf = resHi32 >> 31;
+ return nf;
+ }
+ default:
+ /* shouldn't really make these calls from generated code */
+ vex_printf("armg_calculate_flag_n"
+ "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
+ cc_op, cc_dep1, cc_dep2, cc_dep3 );
+ vpanic("armg_calculate_flags_n");
+ }
}
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-/* Calculate NZCV from the supplied thunk components, in the positions
- they appear in the CPSR, viz bits 31:28 for N Z C V respectively.
- Returned bits 27:0 are zero. */
-UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
- UInt cc_dep2, UInt cc_dep3 )
+/* Calculate the Z flag from the supplied thunk components, in the
+ least significant bit of the word. Returned bits 31:1 are zero. */
+static
+UInt armg_calculate_flag_z ( UInt cc_op, UInt cc_dep1,
+ UInt cc_dep2, UInt cc_dep3 )
{
switch (cc_op) {
- case ARMG_CC_OP_COPY:
- /* (nzcv, unused, unused) */
- return cc_dep1;
+ case ARMG_CC_OP_COPY: {
+ /* (nzcv:28x0, unused, unused) */
+ UInt zf = (cc_dep1 >> ARMG_CC_SHIFT_Z) & 1;
+ return zf;
+ }
case ARMG_CC_OP_ADD: {
/* (argL, argR, unused) */
UInt argL = cc_dep1;
UInt argR = cc_dep2;
UInt res = argL + argR;
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- // CF and VF need verification
- UInt cf = lshift( res < argL, ARMG_CC_SHIFT_C );
- UInt vf = lshift( (res ^ argL) & (res ^ argR),
- ARMG_CC_SHIFT_V + 1 - 32 )
- & ARMG_CC_MASK_V;
- //vex_printf("%08x %08x -> n %x z %x c %x v %x\n",
- // argL, argR, nf, zf, cf, vf);
- return nf | zf | cf | vf;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_SUB: {
/* (argL, argR, unused) */
UInt argL = cc_dep1;
UInt argR = cc_dep2;
UInt res = argL - argR;
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- // XXX cf is inverted relative to normal sense
- UInt cf = lshift( argL >= argR, ARMG_CC_SHIFT_C );
- UInt vf = lshift( (argL ^ argR) & (argL ^ res),
- ARMG_CC_SHIFT_V + 1 - 32 )
- & ARMG_CC_MASK_V;
- //vex_printf("%08x %08x -> n %x z %x c %x v %x\n",
- // argL, argR, nf, zf, cf, vf);
- return nf | zf | cf | vf;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_ADC: {
/* (argL, argR, oldC) */
@@ -111,17 +161,9 @@
UInt argR = cc_dep2;
UInt oldC = cc_dep3;
vassert((oldC & ~1) == 0);
- UInt res = (argL + argR) + oldC;
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- UInt cf = oldC ? lshift( res <= argL, ARMG_CC_SHIFT_C )
- : lshift( res < argL, ARMG_CC_SHIFT_C );
- UInt vf = lshift( (res ^ argL) & (res ^ argR),
- ARMG_CC_SHIFT_V + 1 - 32 )
- & ARMG_CC_MASK_V;
- //vex_printf("%08x %08x -> n %x z %x c %x v %x\n",
- // argL, argR, nf, zf, cf, vf);
- return nf | zf | cf | vf;
+ UInt res = argL + argR + oldC;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_SBB: {
/* (argL, argR, oldC) */
@@ -130,87 +172,216 @@
UInt oldC = cc_dep3;
vassert((oldC & ~1) == 0);
UInt res = argL - argR - (oldC ^ 1);
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- UInt cf = oldC ? lshift( argL >= argR, ARMG_CC_SHIFT_C )
- : lshift( argL > argR, ARMG_CC_SHIFT_C );
- UInt vf = lshift( (argL ^ argR) & (argL ^ res),
- ARMG_CC_SHIFT_V + 1 - 32 )
- & ARMG_CC_MASK_V;
- //vex_printf("%08x %08x -> n %x z %x c %x v %x\n",
- // argL, argR, nf, zf, cf, vf);
- return nf | zf | cf | vf;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_LOGIC: {
/* (res, shco, oldV) */
UInt res = cc_dep1;
- UInt shco = cc_dep2;
- vassert((shco & ~1) == 0);
- UInt oldV = cc_dep3;
- vassert((oldV & ~1) == 0);
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- UInt cf = lshift( shco, ARMG_CC_SHIFT_C );
- UInt vf = lshift( oldV, ARMG_CC_SHIFT_V );
- return nf | zf | cf | vf;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_MUL: {
/* (res, unused, oldC:oldV) */
UInt res = cc_dep1;
- UInt oldC = (cc_dep3 >> 1) & 1;
- UInt oldV = (cc_dep3 >> 0) & 1;
- vassert((cc_dep3 & ~3) == 0);
- UInt nf = lshift( res & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( res == 0, ARMG_CC_SHIFT_Z );
- UInt cf = lshift( oldC, ARMG_CC_SHIFT_C );
- UInt vf = lshift( oldV, ARMG_CC_SHIFT_V );
- return nf | zf | cf | vf;
+ UInt zf = res == 0;
+ return zf;
}
case ARMG_CC_OP_MULL: {
/* (resLo32, resHi32, oldC:oldV) */
UInt resLo32 = cc_dep1;
UInt resHi32 = cc_dep2;
- UInt oldC = (cc_dep3 >> 1) & 1;
- UInt oldV = (cc_dep3 >> 0) & 1;
- vassert((cc_dep3 & ~3) == 0);
- UInt nf = lshift( resHi32 & (1<<31), ARMG_CC_SHIFT_N - 31 );
- UInt zf = lshift( (resHi32|resLo32) == 0, ARMG_CC_SHIFT_Z );
- UInt cf = lshift( oldC, ARMG_CC_SHIFT_C );
- UInt vf = lshift( oldV, ARMG_CC_SHIFT_V );
- return nf | zf | cf | vf;
+ UInt zf = (resHi32|resLo32) == 0;
+ return zf;
}
default:
/* shouldn't really make these calls from generated code */
- vex_printf("armg_calculate_flags_nzcv"
+ vex_printf("armg_calculate_flags_z"
"( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
cc_op, cc_dep1, cc_dep2, cc_dep3 );
- vpanic("armg_calculate_flags_nzcv");
+ vpanic("armg_calculate_flags_z");
}
}
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-/* Calculate the C flag from the thunk components, in the lowest bit
- of the word (bit 0). Bits 31:1 of the returned value are zero. */
+/* Calculate the C flag from the supplied thunk components, in the
+ least significant bit of the word. Returned bits 31:1 are zero. */
UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
UInt cc_dep2, UInt cc_dep3 )
{
- UInt r = armg_calculate_flags_nzcv(cc_op, cc_dep1, cc_dep2, cc_dep3);
- return (r >> ARMG_CC_SHIFT_C) & 1;
+ switch (cc_op) {
+ case ARMG_CC_OP_COPY: {
+ /* (nzcv:28x0, unused, unused) */
+ UInt cf = (cc_dep1 >> ARMG_CC_SHIFT_C) & 1;
+ return cf;
+ }
+ case ARMG_CC_OP_ADD: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt res = argL + argR;
+ UInt cf = res < argL;
+ return cf;
+ }
+ case ARMG_CC_OP_SUB: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt cf = argL >= argR;
+ return cf;
+ }
+ case ARMG_CC_OP_ADC: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt res = argL + argR + oldC;
+ UInt cf = oldC ? (res <= argL) : (res < argL);
+ return cf;
+ }
+ case ARMG_CC_OP_SBB: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt cf = oldC ? (argL >= argR) : (argL > argR);
+ return cf;
+ }
+ case ARMG_CC_OP_LOGIC: {
+ /* (res, shco, oldV) */
+ UInt shco = cc_dep2;
+ vassert((shco & ~1) == 0);
+ UInt cf = shco;
+ return cf;
+ }
+ case ARMG_CC_OP_MUL: {
+ /* (res, unused, oldC:oldV) */
+ UInt oldC = (cc_dep3 >> 1) & 1;
+ vassert((cc_dep3 & ~3) == 0);
+ UInt cf = oldC;
+ return cf;
+ }
+ case ARMG_CC_OP_MULL: {
+ /* (resLo32, resHi32, oldC:oldV) */
+ UInt oldC = (cc_dep3 >> 1) & 1;
+ vassert((cc_dep3 & ~3) == 0);
+ UInt cf = oldC;
+ return cf;
+ }
+ default:
+ /* shouldn't really make these calls from generated code */
+ vex_printf("armg_calculate_flag_c"
+ "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
+ cc_op, cc_dep1, cc_dep2, cc_dep3 );
+ vpanic("armg_calculate_flag_c");
+ }
}
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-/* Calculate the V flag from the thunk components, in the lowest bit
- of the word (bit 0). Bits 31:1 of the returned value are zero. */
+/* Calculate the V flag from the supplied thunk components, in the
+ least significant bit of the word. Returned bits 31:1 are zero. */
UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
UInt cc_dep2, UInt cc_dep3 )
{
- UInt r = armg_calculate_flags_nzcv(cc_op, cc_dep1, cc_dep2, cc_dep3);
- return (r >> ARMG_CC_SHIFT_V) & 1;
+ switch (cc_op) {
+ case ARMG_CC_OP_COPY: {
+ /* (nzcv:28x0, unused, unused) */
+ UInt vf = (cc_dep1 >> ARMG_CC_SHIFT_V) & 1;
+ return vf;
+ }
+ case ARMG_CC_OP_ADD: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt res = argL + argR;
+ UInt vf = ((res ^ argL) & (res ^ argR)) >> 31;
+ return vf;
+ }
+ case ARMG_CC_OP_SUB: {
+ /* (argL, argR, unused) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt res = argL - argR;
+ UInt vf = ((argL ^ argR) & (argL ^ res)) >> 31;
+ return vf;
+ }
+ case ARMG_CC_OP_ADC: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt res = argL + argR + oldC;
+ UInt vf = ((res ^ argL) & (res ^ argR)) >> 31;
+ return vf;
+ }
+ case ARMG_CC_OP_SBB: {
+ /* (argL, argR, oldC) */
+ UInt argL = cc_dep1;
+ UInt argR = cc_dep2;
+ UInt oldC = cc_dep3;
+ vassert((oldC & ~1) == 0);
+ UInt res = argL - argR - (oldC ^ 1);
+ UInt vf = ((argL ^ argR) & (argL ^ res)) >> 31;
+ return vf;
+ }
+ case ARMG_CC_OP_LOGIC: {
+ /* (res, shco, oldV) */
+ UInt oldV = cc_dep3;
+ vassert((oldV & ~1) == 0);
+ UInt vf = oldV;
+ return vf;
+ }
+ case ARMG_CC_OP_MUL: {
+ /* (res, unused, oldC:oldV) */
+ UInt oldV = (cc_dep3 >> 0) & 1;
+ vassert((cc_dep3 & ~3) == 0);
+ UInt vf = oldV;
+ return vf;
+ }
+ case ARMG_CC_OP_MULL: {
+ /* (resLo32, resHi32, oldC:oldV) */
+ UInt oldV = (cc_dep3 >> 0) & 1;
+ vassert((cc_dep3 & ~3) == 0);
+ UInt vf = oldV;
+ return vf;
+ }
+ default:
+ /* shouldn't really make these calls from generated code */
+ vex_printf("armg_calculate_flag_v"
+ "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
+ cc_op, cc_dep1, cc_dep2, cc_dep3 );
+ vpanic("armg_calculate_flag_v");
+ }
}
+
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
+/* Calculate NZCV from the supplied thunk components, in the positions
+ they appear in the CPSR, viz bits 31:28 for N Z C V respectively.
+ Returned bits 27:0 are zero. */
+UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
+ UInt cc_dep2, UInt cc_dep3 )
+{
+ UInt f;
+ UInt res = 0;
+ f = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ res |= (f << ARMG_CC_SHIFT_N);
+ f = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ res |= (f << ARMG_CC_SHIFT_Z);
+ f = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ res |= (f << ARMG_CC_SHIFT_C);
+ f = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ res |= (f << ARMG_CC_SHIFT_V);
+ return res;
+}
+
+
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
/* Calculate the QC flag from the arguments, in the lowest bit
of the word (bit 0). Urr, having this out of line is bizarre.
Push back inline. */
@@ -225,15 +396,14 @@
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
/* Calculate the specified condition from the thunk components, in the
- lowest bit of the word (bit 0). */
-extern
+ lowest bit of the word (bit 0). Returned bits 31:1 are zero. */
UInt armg_calculate_condition ( UInt cond_n_op /* (ARMCondcode << 4) | cc_op */,
UInt cc_dep1,
UInt cc_dep2, UInt cc_dep3 )
{
UInt cond = cond_n_op >> 4;
UInt cc_op = cond_n_op & 0xF;
- UInt nf, zf, vf, cf, nzcv, inv;
+ UInt nf, zf, vf, cf, inv;
// vex_printf("XXXXXXXX %x %x %x %x\n",
// cond_n_op, cc_dep1, cc_dep2, cc_dep3);
@@ -241,47 +411,46 @@
if (cond == ARMCondAL) return 1;
inv = cond & 1;
- nzcv = armg_calculate_flags_nzcv(cc_op, cc_dep1, cc_dep2, cc_dep3);
switch (cond) {
case ARMCondEQ: // Z=1 => z
case ARMCondNE: // Z=0
- zf = nzcv >> ARMG_CC_SHIFT_Z;
- return 1 & (inv ^ zf);
+ zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ zf;
case ARMCondHS: // C=1 => c
case ARMCondLO: // C=0
- cf = nzcv >> ARMG_CC_SHIFT_C;
- return 1 & (inv ^ cf);
+ cf = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ cf;
case ARMCondMI: // N=1 => n
case ARMCondPL: // N=0
- nf = nzcv >> ARMG_CC_SHIFT_N;
- return 1 & (inv ^ nf);
+ nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ nf;
case ARMCondVS: // V=1 => v
case ARMCondVC: // V=0
- vf = nzcv >> ARMG_CC_SHIFT_V;
- return 1 & (inv ^ vf);
+ vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ vf;
case ARMCondHI: // C=1 && Z=0 => c & ~z
case ARMCondLS: // C=0 || Z=1
- cf = nzcv >> ARMG_CC_SHIFT_C;
- zf = nzcv >> ARMG_CC_SHIFT_Z;
- return 1 & (inv ^ (cf & ~zf));
+ cf = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ (cf & ~zf);
case ARMCondGE: // N=V => ~(n^v)
case ARMCondLT: // N!=V
- nf = nzcv >> ARMG_CC_SHIFT_N;
- vf = nzcv >> ARMG_CC_SHIFT_V;
- return 1 & (inv ^ ~(nf ^ vf));
+ nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ (1 & ~(nf ^ vf));
case ARMCondGT: // Z=0 && N=V => ~z & ~(n^v) => ~(z | (n^v))
case ARMCondLE: // Z=1 || N!=V
- nf = nzcv >> ARMG_CC_SHIFT_N;
- vf = nzcv >> ARMG_CC_SHIFT_V;
- zf = nzcv >> ARMG_CC_SHIFT_Z;
- return 1 & (inv ^ ~(zf | (nf ^ vf)));
+ nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
+ return inv ^ (1 & ~(zf | (nf ^ vf)));
case ARMCondAL: // handled above
case ARMCondNV: // should never get here: Illegal instr
|