https://bugs.kde.org/show_bug.cgi?id=386945
--- Comment #14 from Julian Seward <jsew...@acm.org> --- Here's a program that computes the CR.{LT,GT,EQ} bits after "cmplw" using just AND, OR, XOR, NOT, SUB, SHL and SHR. For "cmplw" (the only case tested here so far), it produces the same results as the hardware. Since we have exact V-bit interpretations of all of the abovementioned operations (in mc_translate.c), we should be able to mechanically derive an exact V-bit interpretation of Iop_CmpORD32U. If we do the same for Iop_CmpORD64U and their signed equivalents, we'll be along way along the road to getting these false-positive problems with POWER condition codes fixed. Performance will probably be pretty horrible. But I am hoping that there will be a lot of duplicated expressions in the resulting V-bit DAG, so if those are commoned up it might not be quite so bad. ------------------------ #include <stdio.h> #include <assert.h> typedef unsigned int UInt; __attribute__((noinline)) UInt h_CmpORD32U ( UInt x, UInt y ) { UInt res; __asm__ __volatile__( "" "cmplw 0, %1, %2" "\n\t" "mfcr %0" : /*OUT*/ "=r"(res) : /*IN*/ "r"(x), "r"(y) : /*TRASH*/ "cc", "memory" ); return (res >> 28) & 0xF; } __attribute__((noinline)) UInt s_CmpORD32U ( UInt x, UInt y ) { #if 0 if (x < y) return 8; if (x > y) return 4; return 2; #else /* x-y unsignedly overflows ==> x < y */ UInt x_minus_y_UO = (~x & y) | ((~(x ^ y)) & (x-y)); x_minus_y_UO >>= 31; UInt y_minus_x_UO = (~y & x) | ((~(y ^ x)) & (y-x)); y_minus_x_UO >>= 31; //UInt res = (x_minus_y_UO << 3) | (y_minus_x_UO << 2); //if (res == 0) res = 2; UInt x_eq_y = (x_minus_y_UO | y_minus_x_UO) ^ 1; UInt res = (x_minus_y_UO << 3) | (y_minus_x_UO << 2) | (x_eq_y << 1); return res; #endif } const UInt vals[] = { 0x0, 0x1, 0x2, 0x3ffffffeU, 0x3fffffffU, 0x40000000U, 0x40000001U, 0x40000002U, 0x7ffffffeU, 0x7fffffffU, 0x80000000U, 0x80000001U, 0x80000002U, 0xbffffffeU, 0xbfffffffU, 0xc0000000U, 0xc0000001U, 0xc0000002U, 0xfffffffdU, 0xfffffffeU, 0xffffffffU }; int main ( void ) { UInt xi, yi; const UInt nElem = sizeof(vals) / sizeof(vals[0]); for (xi = 0; xi < nElem; xi++) { for (yi = 0; yi < nElem; yi++) { UInt x = vals[xi]; UInt y = vals[yi]; UInt resHU = h_CmpORD32U(x, y); UInt resSU = s_CmpORD32U(x, y); printf("%08x %08x -> %02x %02x\n", x, y, resHU, resSU); assert(resHU == resSU); } } return 0; } -- You are receiving this mail because: You are watching all bug changes.