Loading libpixelflinger/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif ifeq ($(TARGET_ARCH),mips) PIXELFLINGER_SRC_FILES += codeflinger/MIPSAssembler.cpp PIXELFLINGER_SRC_FILES += codeflinger/mips_disassem.c PIXELFLINGER_SRC_FILES += arch-mips/t32cb16blend.S PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif Loading libpixelflinger/codeflinger/ARMAssembler.cpp +146 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,11 @@ void ARMAssembler::reset() mComments.clear(); } int ARMAssembler::getCodegenArch() { return CODEGEN_ARCH_ARM; } // ---------------------------------------------------------------------------- void ARMAssembler::disassemble(const char* name) Loading Loading @@ -444,5 +449,146 @@ 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; } #if 0 #pragma mark - #pragma mark Addressing modes... #endif int ARMAssembler::buildImmediate( uint32_t immediate, uint32_t& rot, uint32_t& imm) { rot = 0; imm = immediate; if (imm > 0x7F) { // skip the easy cases while (!(imm&3) || (imm&0xFC000000)) { uint32_t newval; newval = imm >> 2; newval |= (imm&3) << 30; imm = newval; rot += 2; if (rot == 32) { rot = 0; break; } } } rot = (16 - (rot>>1)) & 0xF; if (imm>=0x100) return -EINVAL; if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) return -1; return 0; } // shifters... bool ARMAssembler::isValidImmediate(uint32_t immediate) { uint32_t rot, imm; return buildImmediate(immediate, rot, imm) == 0; } uint32_t ARMAssembler::imm(uint32_t immediate) { uint32_t rot, imm; int err = buildImmediate(immediate, rot, imm); LOG_ALWAYS_FATAL_IF(err==-EINVAL, "immediate %08x cannot be encoded", immediate); LOG_ALWAYS_FATAL_IF(err, "immediate (%08x) encoding bogus!", immediate); return (1<<25) | (rot<<8) | imm; } uint32_t ARMAssembler::reg_imm(int Rm, int type, uint32_t shift) { return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); } uint32_t ARMAssembler::reg_rrx(int Rm) { return (ROR<<5) | (Rm&0xF); } uint32_t ARMAssembler::reg_reg(int Rm, int type, int Rs) { return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); } // addressing modes... // LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssembler::immed12_pre(int32_t immed12, int W) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (1<<24) | (((uint32_t(immed12)>>31)^1)<<23) | ((W&1)<<21) | (abs(immed12)&0x7FF); } uint32_t ARMAssembler::immed12_post(int32_t immed12) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); } uint32_t ARMAssembler::reg_scale_pre(int Rm, int type, uint32_t shift, int W) { return (1<<25) | (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | reg_imm(abs(Rm), type, shift); } uint32_t ARMAssembler::reg_scale_post(int Rm, int type, uint32_t shift) { return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); } // LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssembler::immed8_pre(int32_t immed8, int W) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<24) | (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); } uint32_t ARMAssembler::immed8_post(int32_t immed8) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | (((offset&0xF0)<<4) | (offset&0xF)); } uint32_t ARMAssembler::reg_pre(int Rm, int W) { return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); } uint32_t ARMAssembler::reg_post(int Rm) { return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); } }; // namespace android libpixelflinger/codeflinger/ARMAssembler.h +41 −8 Original line number Diff line number Diff line Loading @@ -52,11 +52,42 @@ public: virtual void reset(); virtual int generate(const char* name); virtual int getCodegenArch(); virtual void prolog(); virtual void epilog(uint32_t touched); virtual void comment(const char* string); // ----------------------------------------------------------------------- // shifters and addressing modes // ----------------------------------------------------------------------- // shifters... virtual bool isValidImmediate(uint32_t immed); virtual int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm); virtual uint32_t imm(uint32_t immediate); virtual uint32_t reg_imm(int Rm, int type, uint32_t shift); virtual uint32_t reg_rrx(int Rm); virtual uint32_t reg_reg(int Rm, int type, int Rs); // addressing modes... // LDR(B)/STR(B)/PLD // (immediate and Rm can be negative, which indicates U=0) virtual uint32_t immed12_pre(int32_t immed12, int W=0); virtual uint32_t immed12_post(int32_t immed12); virtual uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0); virtual uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0); // LDRH/LDRSB/LDRSH/STRH // (immediate and Rm can be negative, which indicates U=0) virtual uint32_t immed8_pre(int32_t immed8, int W=0); virtual uint32_t immed8_post(int32_t immed8); virtual uint32_t reg_pre(int Rm, int W=0); virtual uint32_t reg_post(int Rm); virtual void dataProcessing(int opcode, int cc, int s, int Rd, int Rn, uint32_t Op2); Loading @@ -83,21 +114,23 @@ public: virtual uint32_t* pcForLabel(const char* label); virtual void LDR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void LDRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void STR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void STRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void LDRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDRSB(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDRSH(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void STRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDM(int cc, int dir, int Rn, int W, uint32_t reg_list); virtual void STM(int cc, int dir, Loading libpixelflinger/codeflinger/ARMAssemblerInterface.cpp +8 −115 Original line number Diff line number Diff line Loading @@ -32,77 +32,15 @@ ARMAssemblerInterface::~ARMAssemblerInterface() { } int ARMAssemblerInterface::buildImmediate( uint32_t immediate, uint32_t& rot, uint32_t& imm) { rot = 0; imm = immediate; if (imm > 0x7F) { // skip the easy cases while (!(imm&3) || (imm&0xFC000000)) { uint32_t newval; newval = imm >> 2; newval |= (imm&3) << 30; imm = newval; rot += 2; if (rot == 32) { rot = 0; break; } } } rot = (16 - (rot>>1)) & 0xF; if (imm>=0x100) return -EINVAL; if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) return -1; return 0; } // shifters... // -------------------------------------------------------------------- bool ARMAssemblerInterface::isValidImmediate(uint32_t immediate) { uint32_t rot, imm; return buildImmediate(immediate, rot, imm) == 0; } // The following two functions are static and used for initializers // in the original ARM code. The above versions (without __), are now // virtual, and can be overridden in the MIPS code. But since these are // needed at initialization time, they must be static. Not thrilled with // this implementation, but it works... uint32_t ARMAssemblerInterface::imm(uint32_t immediate) { uint32_t rot, imm; int err = buildImmediate(immediate, rot, imm); LOG_ALWAYS_FATAL_IF(err==-EINVAL, "immediate %08x cannot be encoded", immediate); LOG_ALWAYS_FATAL_IF(err, "immediate (%08x) encoding bogus!", immediate); return (1<<25) | (rot<<8) | imm; } uint32_t ARMAssemblerInterface::reg_imm(int Rm, int type, uint32_t shift) { return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); } uint32_t ARMAssemblerInterface::reg_rrx(int Rm) { return (ROR<<5) | (Rm&0xF); } uint32_t ARMAssemblerInterface::reg_reg(int Rm, int type, int Rs) { return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); } // addressing modes... // LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) uint32_t ARMAssemblerInterface::__immed12_pre(int32_t immed12, int W) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", Loading @@ -111,30 +49,7 @@ uint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) ((W&1)<<21) | (abs(immed12)&0x7FF); } uint32_t ARMAssemblerInterface::immed12_post(int32_t immed12) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); } uint32_t ARMAssemblerInterface::reg_scale_pre(int Rm, int type, uint32_t shift, int W) { return (1<<25) | (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | reg_imm(abs(Rm), type, shift); } uint32_t ARMAssemblerInterface::reg_scale_post(int Rm, int type, uint32_t shift) { return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); } // LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) uint32_t ARMAssemblerInterface::__immed8_pre(int32_t immed8, int W) { uint32_t offset = abs(immed8); Loading @@ -146,28 +61,6 @@ uint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); } uint32_t ARMAssemblerInterface::immed8_post(int32_t immed8) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | (((offset&0xF0)<<4) | (offset&0xF)); } uint32_t ARMAssemblerInterface::reg_pre(int Rm, int W) { return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); } uint32_t ARMAssemblerInterface::reg_post(int Rm) { return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); } }; // namespace android libpixelflinger/codeflinger/ARMAssemblerInterface.h +31 −23 Original line number Diff line number Diff line Loading @@ -62,33 +62,40 @@ public: LSAVED = LR4|LR5|LR6|LR7|LR8|LR9|LR10|LR11 | LLR }; enum { CODEGEN_ARCH_ARM = 1, CODEGEN_ARCH_MIPS }; // ----------------------------------------------------------------------- // shifters and addressing modes // ----------------------------------------------------------------------- // shifters... static bool isValidImmediate(uint32_t immed); static int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm); // these static versions are used for initializers on LDxx/STxx below static uint32_t __immed12_pre(int32_t immed12, int W=0); static uint32_t __immed8_pre(int32_t immed12, int W=0); virtual bool isValidImmediate(uint32_t immed) = 0; virtual int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm) = 0; static uint32_t imm(uint32_t immediate); static uint32_t reg_imm(int Rm, int type, uint32_t shift); static uint32_t reg_rrx(int Rm); static uint32_t reg_reg(int Rm, int type, int Rs); virtual uint32_t imm(uint32_t immediate) = 0; virtual uint32_t reg_imm(int Rm, int type, uint32_t shift) = 0; virtual uint32_t reg_rrx(int Rm) = 0; virtual uint32_t reg_reg(int Rm, int type, int Rs) = 0; // addressing modes... // LDR(B)/STR(B)/PLD // (immediate and Rm can be negative, which indicates U=0) static uint32_t immed12_pre(int32_t immed12, int W=0); static uint32_t immed12_post(int32_t immed12); static uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0); static uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0); virtual uint32_t immed12_pre(int32_t immed12, int W=0) = 0; virtual uint32_t immed12_post(int32_t immed12) = 0; virtual uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0) = 0; virtual uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0) = 0; // LDRH/LDRSB/LDRSH/STRH // (immediate and Rm can be negative, which indicates U=0) static uint32_t immed8_pre(int32_t immed8, int W=0); static uint32_t immed8_post(int32_t immed8); static uint32_t reg_pre(int Rm, int W=0); static uint32_t reg_post(int Rm); virtual uint32_t immed8_pre(int32_t immed8, int W=0) = 0; virtual uint32_t immed8_post(int32_t immed8) = 0; virtual uint32_t reg_pre(int Rm, int W=0) = 0; virtual uint32_t reg_post(int Rm) = 0; // ----------------------------------------------------------------------- // basic instructions & code generation Loading @@ -98,6 +105,7 @@ public: virtual void reset() = 0; virtual int generate(const char* name) = 0; virtual void disassemble(const char* name) = 0; virtual int getCodegenArch() = 0; // construct prolog and epilog virtual void prolog() = 0; Loading Loading @@ -143,22 +151,22 @@ public: // data transfer... virtual void LDR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void LDRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void STR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void STRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void LDRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void LDRSB(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void LDRSH(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void STRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; // block data transfer... virtual void LDM(int cc, int dir, Loading Loading
libpixelflinger/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif ifeq ($(TARGET_ARCH),mips) PIXELFLINGER_SRC_FILES += codeflinger/MIPSAssembler.cpp PIXELFLINGER_SRC_FILES += codeflinger/mips_disassem.c PIXELFLINGER_SRC_FILES += arch-mips/t32cb16blend.S PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif Loading
libpixelflinger/codeflinger/ARMAssembler.cpp +146 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,11 @@ void ARMAssembler::reset() mComments.clear(); } int ARMAssembler::getCodegenArch() { return CODEGEN_ARCH_ARM; } // ---------------------------------------------------------------------------- void ARMAssembler::disassemble(const char* name) Loading Loading @@ -444,5 +449,146 @@ 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; } #if 0 #pragma mark - #pragma mark Addressing modes... #endif int ARMAssembler::buildImmediate( uint32_t immediate, uint32_t& rot, uint32_t& imm) { rot = 0; imm = immediate; if (imm > 0x7F) { // skip the easy cases while (!(imm&3) || (imm&0xFC000000)) { uint32_t newval; newval = imm >> 2; newval |= (imm&3) << 30; imm = newval; rot += 2; if (rot == 32) { rot = 0; break; } } } rot = (16 - (rot>>1)) & 0xF; if (imm>=0x100) return -EINVAL; if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) return -1; return 0; } // shifters... bool ARMAssembler::isValidImmediate(uint32_t immediate) { uint32_t rot, imm; return buildImmediate(immediate, rot, imm) == 0; } uint32_t ARMAssembler::imm(uint32_t immediate) { uint32_t rot, imm; int err = buildImmediate(immediate, rot, imm); LOG_ALWAYS_FATAL_IF(err==-EINVAL, "immediate %08x cannot be encoded", immediate); LOG_ALWAYS_FATAL_IF(err, "immediate (%08x) encoding bogus!", immediate); return (1<<25) | (rot<<8) | imm; } uint32_t ARMAssembler::reg_imm(int Rm, int type, uint32_t shift) { return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); } uint32_t ARMAssembler::reg_rrx(int Rm) { return (ROR<<5) | (Rm&0xF); } uint32_t ARMAssembler::reg_reg(int Rm, int type, int Rs) { return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); } // addressing modes... // LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssembler::immed12_pre(int32_t immed12, int W) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (1<<24) | (((uint32_t(immed12)>>31)^1)<<23) | ((W&1)<<21) | (abs(immed12)&0x7FF); } uint32_t ARMAssembler::immed12_post(int32_t immed12) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); } uint32_t ARMAssembler::reg_scale_pre(int Rm, int type, uint32_t shift, int W) { return (1<<25) | (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | reg_imm(abs(Rm), type, shift); } uint32_t ARMAssembler::reg_scale_post(int Rm, int type, uint32_t shift) { return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); } // LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssembler::immed8_pre(int32_t immed8, int W) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<24) | (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); } uint32_t ARMAssembler::immed8_post(int32_t immed8) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | (((offset&0xF0)<<4) | (offset&0xF)); } uint32_t ARMAssembler::reg_pre(int Rm, int W) { return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); } uint32_t ARMAssembler::reg_post(int Rm) { return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); } }; // namespace android
libpixelflinger/codeflinger/ARMAssembler.h +41 −8 Original line number Diff line number Diff line Loading @@ -52,11 +52,42 @@ public: virtual void reset(); virtual int generate(const char* name); virtual int getCodegenArch(); virtual void prolog(); virtual void epilog(uint32_t touched); virtual void comment(const char* string); // ----------------------------------------------------------------------- // shifters and addressing modes // ----------------------------------------------------------------------- // shifters... virtual bool isValidImmediate(uint32_t immed); virtual int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm); virtual uint32_t imm(uint32_t immediate); virtual uint32_t reg_imm(int Rm, int type, uint32_t shift); virtual uint32_t reg_rrx(int Rm); virtual uint32_t reg_reg(int Rm, int type, int Rs); // addressing modes... // LDR(B)/STR(B)/PLD // (immediate and Rm can be negative, which indicates U=0) virtual uint32_t immed12_pre(int32_t immed12, int W=0); virtual uint32_t immed12_post(int32_t immed12); virtual uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0); virtual uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0); // LDRH/LDRSB/LDRSH/STRH // (immediate and Rm can be negative, which indicates U=0) virtual uint32_t immed8_pre(int32_t immed8, int W=0); virtual uint32_t immed8_post(int32_t immed8); virtual uint32_t reg_pre(int Rm, int W=0); virtual uint32_t reg_post(int Rm); virtual void dataProcessing(int opcode, int cc, int s, int Rd, int Rn, uint32_t Op2); Loading @@ -83,21 +114,23 @@ public: virtual uint32_t* pcForLabel(const char* label); virtual void LDR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void LDRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void STR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void STRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)); int Rn, uint32_t offset = __immed12_pre(0)); virtual void LDRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDRSB(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDRSH(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void STRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)); int Rn, uint32_t offset = __immed8_pre(0)); virtual void LDM(int cc, int dir, int Rn, int W, uint32_t reg_list); virtual void STM(int cc, int dir, Loading
libpixelflinger/codeflinger/ARMAssemblerInterface.cpp +8 −115 Original line number Diff line number Diff line Loading @@ -32,77 +32,15 @@ ARMAssemblerInterface::~ARMAssemblerInterface() { } int ARMAssemblerInterface::buildImmediate( uint32_t immediate, uint32_t& rot, uint32_t& imm) { rot = 0; imm = immediate; if (imm > 0x7F) { // skip the easy cases while (!(imm&3) || (imm&0xFC000000)) { uint32_t newval; newval = imm >> 2; newval |= (imm&3) << 30; imm = newval; rot += 2; if (rot == 32) { rot = 0; break; } } } rot = (16 - (rot>>1)) & 0xF; if (imm>=0x100) return -EINVAL; if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) return -1; return 0; } // shifters... // -------------------------------------------------------------------- bool ARMAssemblerInterface::isValidImmediate(uint32_t immediate) { uint32_t rot, imm; return buildImmediate(immediate, rot, imm) == 0; } // The following two functions are static and used for initializers // in the original ARM code. The above versions (without __), are now // virtual, and can be overridden in the MIPS code. But since these are // needed at initialization time, they must be static. Not thrilled with // this implementation, but it works... uint32_t ARMAssemblerInterface::imm(uint32_t immediate) { uint32_t rot, imm; int err = buildImmediate(immediate, rot, imm); LOG_ALWAYS_FATAL_IF(err==-EINVAL, "immediate %08x cannot be encoded", immediate); LOG_ALWAYS_FATAL_IF(err, "immediate (%08x) encoding bogus!", immediate); return (1<<25) | (rot<<8) | imm; } uint32_t ARMAssemblerInterface::reg_imm(int Rm, int type, uint32_t shift) { return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); } uint32_t ARMAssemblerInterface::reg_rrx(int Rm) { return (ROR<<5) | (Rm&0xF); } uint32_t ARMAssemblerInterface::reg_reg(int Rm, int type, int Rs) { return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); } // addressing modes... // LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) uint32_t ARMAssemblerInterface::__immed12_pre(int32_t immed12, int W) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", Loading @@ -111,30 +49,7 @@ uint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) ((W&1)<<21) | (abs(immed12)&0x7FF); } uint32_t ARMAssemblerInterface::immed12_post(int32_t immed12) { LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, "LDR(B)/STR(B)/PLD immediate too big (%08x)", immed12); return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); } uint32_t ARMAssemblerInterface::reg_scale_pre(int Rm, int type, uint32_t shift, int W) { return (1<<25) | (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | reg_imm(abs(Rm), type, shift); } uint32_t ARMAssemblerInterface::reg_scale_post(int Rm, int type, uint32_t shift) { return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); } // LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) uint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) uint32_t ARMAssemblerInterface::__immed8_pre(int32_t immed8, int W) { uint32_t offset = abs(immed8); Loading @@ -146,28 +61,6 @@ uint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); } uint32_t ARMAssemblerInterface::immed8_post(int32_t immed8) { uint32_t offset = abs(immed8); LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", immed8); return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | (((offset&0xF0)<<4) | (offset&0xF)); } uint32_t ARMAssemblerInterface::reg_pre(int Rm, int W) { return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); } uint32_t ARMAssemblerInterface::reg_post(int Rm) { return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); } }; // namespace android
libpixelflinger/codeflinger/ARMAssemblerInterface.h +31 −23 Original line number Diff line number Diff line Loading @@ -62,33 +62,40 @@ public: LSAVED = LR4|LR5|LR6|LR7|LR8|LR9|LR10|LR11 | LLR }; enum { CODEGEN_ARCH_ARM = 1, CODEGEN_ARCH_MIPS }; // ----------------------------------------------------------------------- // shifters and addressing modes // ----------------------------------------------------------------------- // shifters... static bool isValidImmediate(uint32_t immed); static int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm); // these static versions are used for initializers on LDxx/STxx below static uint32_t __immed12_pre(int32_t immed12, int W=0); static uint32_t __immed8_pre(int32_t immed12, int W=0); virtual bool isValidImmediate(uint32_t immed) = 0; virtual int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm) = 0; static uint32_t imm(uint32_t immediate); static uint32_t reg_imm(int Rm, int type, uint32_t shift); static uint32_t reg_rrx(int Rm); static uint32_t reg_reg(int Rm, int type, int Rs); virtual uint32_t imm(uint32_t immediate) = 0; virtual uint32_t reg_imm(int Rm, int type, uint32_t shift) = 0; virtual uint32_t reg_rrx(int Rm) = 0; virtual uint32_t reg_reg(int Rm, int type, int Rs) = 0; // addressing modes... // LDR(B)/STR(B)/PLD // (immediate and Rm can be negative, which indicates U=0) static uint32_t immed12_pre(int32_t immed12, int W=0); static uint32_t immed12_post(int32_t immed12); static uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0); static uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0); virtual uint32_t immed12_pre(int32_t immed12, int W=0) = 0; virtual uint32_t immed12_post(int32_t immed12) = 0; virtual uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0) = 0; virtual uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0) = 0; // LDRH/LDRSB/LDRSH/STRH // (immediate and Rm can be negative, which indicates U=0) static uint32_t immed8_pre(int32_t immed8, int W=0); static uint32_t immed8_post(int32_t immed8); static uint32_t reg_pre(int Rm, int W=0); static uint32_t reg_post(int Rm); virtual uint32_t immed8_pre(int32_t immed8, int W=0) = 0; virtual uint32_t immed8_post(int32_t immed8) = 0; virtual uint32_t reg_pre(int Rm, int W=0) = 0; virtual uint32_t reg_post(int Rm) = 0; // ----------------------------------------------------------------------- // basic instructions & code generation Loading @@ -98,6 +105,7 @@ public: virtual void reset() = 0; virtual int generate(const char* name) = 0; virtual void disassemble(const char* name) = 0; virtual int getCodegenArch() = 0; // construct prolog and epilog virtual void prolog() = 0; Loading Loading @@ -143,22 +151,22 @@ public: // data transfer... virtual void LDR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void LDRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void STR (int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void STRB(int cc, int Rd, int Rn, uint32_t offset = immed12_pre(0)) = 0; int Rn, uint32_t offset = __immed12_pre(0)) = 0; virtual void LDRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void LDRSB(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void LDRSH(int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; virtual void STRH (int cc, int Rd, int Rn, uint32_t offset = immed8_pre(0)) = 0; int Rn, uint32_t offset = __immed8_pre(0)) = 0; // block data transfer... virtual void LDM(int cc, int dir, Loading