diff --git a/libpixelflinger/codeflinger/ARMAssembler.cpp b/libpixelflinger/codeflinger/ARMAssembler.cpp index d3720c3ee..fa9f1ade8 100644 --- a/libpixelflinger/codeflinger/ARMAssembler.cpp +++ b/libpixelflinger/codeflinger/ARMAssembler.cpp @@ -433,6 +433,16 @@ void ARMAssembler::UXTB16(int cc, int Rd, int Rm, int rotate) { *mPC++ = (cc<<28) | 0x6CF0070 | (Rd<<12) | ((rotate >> 3) << 10) | Rm; } +#if 0 +#pragma mark - +#pragma mark Bit manipulation (ARMv7+ only)... +#endif + +// Bit manipulation (ARMv7+ only)... +void ARMAssembler::UBFX(int cc, int Rd, int Rn, int lsb, int width) +{ + *mPC++ = (cc<<28) | 0x7E00000 | ((width-1)<<16) | (Rd<<12) | (lsb<<7) | 0x50 | Rn; +} }; // namespace android diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h index a667cb511..e7f038ae4 100644 --- a/libpixelflinger/codeflinger/ARMAssembler.h +++ b/libpixelflinger/codeflinger/ARMAssembler.h @@ -124,6 +124,7 @@ public: virtual void SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn); virtual void UXTB16(int cc, int Rd, int Rm, int rotate); + virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width); private: ARMAssembler(const ARMAssembler& rhs); diff --git a/libpixelflinger/codeflinger/ARMAssemblerInterface.h b/libpixelflinger/codeflinger/ARMAssemblerInterface.h index ff6af2a22..796342a06 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerInterface.h +++ b/libpixelflinger/codeflinger/ARMAssemblerInterface.h @@ -206,6 +206,9 @@ public: // byte/half word extract... virtual void UXTB16(int cc, int Rd, int Rm, int rotate) = 0; + // bit manipulation... + virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width) = 0; + // ----------------------------------------------------------------------- // convenience... // ----------------------------------------------------------------------- diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp index 7c422dbad..c57d7daa9 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp +++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp @@ -199,5 +199,9 @@ void ARMAssemblerProxy::UXTB16(int cc, int Rd, int Rm, int rotate) { mTarget->UXTB16(cc, Rd, Rm, rotate); } +void ARMAssemblerProxy::UBFX(int cc, int Rd, int Rn, int lsb, int width) { + mTarget->UBFX(cc, Rd, Rn, lsb, width); +} + }; // namespace android diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.h b/libpixelflinger/codeflinger/ARMAssemblerProxy.h index 9134cce6f..8c7f2707f 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.h +++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.h @@ -115,6 +115,7 @@ public: int Rd, int Rm, int Rs, int Rn); virtual void UXTB16(int cc, int Rd, int Rm, int rotate); + virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width); private: ARMAssemblerInterface* mTarget; diff --git a/libpixelflinger/codeflinger/disassem.c b/libpixelflinger/codeflinger/disassem.c index c17f3ecc1..aeb80340a 100644 --- a/libpixelflinger/codeflinger/disassem.c +++ b/libpixelflinger/codeflinger/disassem.c @@ -81,6 +81,8 @@ * g - 2nd fp operand (register) (bits 16-18) * h - 3rd fp operand (register/immediate) (bits 0-4) * j - xtb rotate literal (bits 10-11) + * i - bfx lsb literal (bits 7-11) + * w - bfx width literal (bits 16-20) * b - branch address * t - thumb branch address (bits 24, 0-23) * k - breakpoint comment (bits 0-3, 8-19) @@ -124,6 +126,7 @@ static const struct arm32_insn arm32_i[] = { { 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" }, { 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" }, { 0x0fff03f0, 0x06cf0070, "uxtb16", "dmj" }, + { 0x0fe00070, 0x07e00050, "ubfx", "dmiw" }, { 0x0d700000, 0x04200000, "strt", "daW" }, { 0x0d700000, 0x04300000, "ldrt", "daW" }, { 0x0d700000, 0x04600000, "strbt", "daW" }, @@ -412,6 +415,14 @@ disasm(const disasm_interface_t *di, u_int loc, int altfmt) case 'j': di->di_printf("ror #%d", ((insn >> 10) & 3) << 3); break; + /* i - bfx lsb literal (bits 7-11) */ + case 'i': + di->di_printf("#%d", (insn >> 7) & 31); + break; + /* w - bfx width literal (bits 16-20) */ + case 'w': + di->di_printf("#%d", 1 + ((insn >> 16) & 31)); + break; /* b - branch address */ case 'b': branch = ((insn << 2) & 0x03ffffff); diff --git a/libpixelflinger/codeflinger/load_store.cpp b/libpixelflinger/codeflinger/load_store.cpp index 93c582579..ed20a0011 100644 --- a/libpixelflinger/codeflinger/load_store.cpp +++ b/libpixelflinger/codeflinger/load_store.cpp @@ -18,9 +18,12 @@ #include #include #include - #include "codeflinger/GGLAssembler.h" +#ifdef __ARM_ARCH__ +#include +#endif + namespace android { // ---------------------------------------------------------------------------- @@ -110,6 +113,20 @@ void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits) assert(maskLen<=8); assert(h); +#if __ARM_ARCH__ >= 7 + const int mask = (1<> l; + } else if (!l && isValidImmediate(mask)) { + AND(AL, 0, d.reg, s, imm(mask)); // component = packed & mask; + } else if (!l && isValidImmediate(~mask)) { + BIC(AL, 0, d.reg, s, imm(~mask)); // component = packed & mask; + } else { + UBFX(AL, d.reg, s, l, maskLen); // component = (packed & mask) >> l; + } +#else if (h != bits) { const int mask = ((1<