diff options
author | Martyn Capewell <martyn.capewell@arm.com> | 2009-12-04 16:44:58 +0000 |
---|---|---|
committer | Dave Butcher <david.butcher@arm.com> | 2010-05-28 17:04:36 +0100 |
commit | 4dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3 (patch) | |
tree | 6660a0eaa05954ba69f0693b5ee52fad94860c7c | |
parent | 67d5358e2a870f9e9447517bfa49bf5c6b410a50 (diff) | |
download | system_core-4dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3.zip system_core-4dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3.tar.gz system_core-4dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3.tar.bz2 |
Adds support for UBFX to JIT and Disassembler
This introduces UBFX instruction generation abilities to the Pixelflinger JIT,
and also modifies the component extraction function to generate the
instruction.
The extract function contains defines to prevent generation of UBFX on pre-v7
cores. The JIT itself retains the ability to produce the instruction even on
v5/6.
This patch only generates UBFX when MOV, AND or BIC can't be used. Based on
the TRM, this appears to be faster on A9 than using UBFX in all cases.
On startup, Pixelflinger JITs three chunks of code. UBFX improves these as
follows:
00000077:03515104_00000000_00000000
(Blends a single colour into an RGB565 buffer.)
Before: 27 inst/pixel, After: 24 inst/pixel, Improvement: 12.5%
00000077:03545404_00000A01_00000000
(Blends RGBA8888 texture into an RGB565 buffer using alpha.)
Before: 30 inst/pixel, After: 27 inst/pixel, Improvement: 11.1%
00000077:03545404_00000A04_00000000
(Blends RGB565 texture into an RGB565 buffer using alpha.)
Before: 29 inst/pixel, After: 27 inst/pixel, Improvement: 7.4%
-rw-r--r-- | libpixelflinger/codeflinger/ARMAssembler.cpp | 10 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/ARMAssembler.h | 1 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerInterface.h | 3 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerProxy.cpp | 4 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerProxy.h | 1 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/disassem.c | 11 | ||||
-rw-r--r-- | libpixelflinger/codeflinger/load_store.cpp | 18 |
7 files changed, 47 insertions, 1 deletions
diff --git a/libpixelflinger/codeflinger/ARMAssembler.cpp b/libpixelflinger/codeflinger/ARMAssembler.cpp index d3720c3..fa9f1ad 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 a667cb5..e7f038a 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 ff6af2a..796342a 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 7c422db..c57d7da 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 9134cce..8c7f270 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 c17f3ec..aeb8034 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 93c5825..023381c 100644 --- a/libpixelflinger/codeflinger/load_store.cpp +++ b/libpixelflinger/codeflinger/load_store.cpp @@ -18,9 +18,10 @@ #include <assert.h> #include <stdio.h> #include <cutils/log.h> - #include "codeflinger/GGLAssembler.h" +#include <machine/cpu-features.h> + namespace android { // ---------------------------------------------------------------------------- @@ -110,6 +111,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<<maskLen)-1; + if ((h == bits) && !l && (s != d.reg)) { + MOV(AL, 0, d.reg, s); // component = packed; + } else if ((h == bits) && l) { + MOV(AL, 0, d.reg, reg_imm(s, LSR, l)); // component = packed >> 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<<maskLen)-1) << l; if (isValidImmediate(mask)) { @@ -132,6 +147,7 @@ void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits) if (s != d.reg) { MOV(AL, 0, d.reg, s); } +#endif d.s = maskLen; } |