bfc6dc4ca8
GGLAssembler assumes addresses to be 32-bit and uses ARM 32-bit instructions to load/store/manipulate addresses. To support, 64-bit architectures, following changes has been done 1. ARMAssemblerInterface has been extended to support four new operations ADDR_LDR, ADDR_STR, ADDR_SUB, ADDR_ADD. Base class implements these virtual functions to use 32bit equivalent function. This avoids existing 32-bit Assembler backend implementations like ARMAssembler and MIPSAssembler from mapping the new functions to existing equivalent routines. This also allows 64-bit Architectures like AArch64 to override the function in their assembler backend implementations. 2. GGLAssembler code (spread over GGLAssembler.cpp, GGLAssembler.h and texturing.cpp) has been changed to use the new operations for address operations. Change-Id: I3d7eace4691e3e47cef737d97ac67ce6ef4fb18d Signed-off-by: Ashok Bhat <ashok.bhat@arm.com>
311 lines
8.4 KiB
C++
311 lines
8.4 KiB
C++
/* libs/pixelflinger/codeflinger/ARMAssemblerProxy.cpp
|
|
**
|
|
** Copyright 2006, The Android Open Source Project
|
|
**
|
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
** you may not use this file except in compliance with the License.
|
|
** You may obtain a copy of the License at
|
|
**
|
|
** http://www.apache.org/licenses/LICENSE-2.0
|
|
**
|
|
** Unless required by applicable law or agreed to in writing, software
|
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
** See the License for the specific language governing permissions and
|
|
** limitations under the License.
|
|
*/
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
#include "ARMAssemblerProxy.h"
|
|
|
|
namespace android {
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
ARMAssemblerProxy::ARMAssemblerProxy()
|
|
: mTarget(0)
|
|
{
|
|
}
|
|
|
|
ARMAssemblerProxy::ARMAssemblerProxy(ARMAssemblerInterface* target)
|
|
: mTarget(target)
|
|
{
|
|
}
|
|
|
|
ARMAssemblerProxy::~ARMAssemblerProxy()
|
|
{
|
|
delete mTarget;
|
|
}
|
|
|
|
void ARMAssemblerProxy::setTarget(ARMAssemblerInterface* target)
|
|
{
|
|
delete mTarget;
|
|
mTarget = target;
|
|
}
|
|
|
|
void ARMAssemblerProxy::reset() {
|
|
mTarget->reset();
|
|
}
|
|
int ARMAssemblerProxy::generate(const char* name) {
|
|
return mTarget->generate(name);
|
|
}
|
|
void ARMAssemblerProxy::disassemble(const char* name) {
|
|
return mTarget->disassemble(name);
|
|
}
|
|
int ARMAssemblerProxy::getCodegenArch()
|
|
{
|
|
return mTarget->getCodegenArch();
|
|
}
|
|
void ARMAssemblerProxy::prolog() {
|
|
mTarget->prolog();
|
|
}
|
|
void ARMAssemblerProxy::epilog(uint32_t touched) {
|
|
mTarget->epilog(touched);
|
|
}
|
|
void ARMAssemblerProxy::comment(const char* string) {
|
|
mTarget->comment(string);
|
|
}
|
|
|
|
|
|
|
|
// addressing modes
|
|
|
|
bool ARMAssemblerProxy::isValidImmediate(uint32_t immed)
|
|
{
|
|
return mTarget->isValidImmediate(immed);
|
|
}
|
|
|
|
int ARMAssemblerProxy::buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm)
|
|
{
|
|
return mTarget->buildImmediate(i, rot, imm);
|
|
}
|
|
|
|
|
|
|
|
uint32_t ARMAssemblerProxy::imm(uint32_t immediate)
|
|
{
|
|
return mTarget->imm(immediate);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_imm(int Rm, int type, uint32_t shift)
|
|
{
|
|
return mTarget->reg_imm(Rm, type, shift);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_rrx(int Rm)
|
|
{
|
|
return mTarget->reg_rrx(Rm);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_reg(int Rm, int type, int Rs)
|
|
{
|
|
return mTarget->reg_reg(Rm, type, Rs);
|
|
}
|
|
|
|
|
|
// addressing modes...
|
|
// LDR(B)/STR(B)/PLD
|
|
// (immediate and Rm can be negative, which indicates U=0)
|
|
uint32_t ARMAssemblerProxy::immed12_pre(int32_t immed12, int W)
|
|
{
|
|
return mTarget->immed12_pre(immed12, W);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::immed12_post(int32_t immed12)
|
|
{
|
|
return mTarget->immed12_post(immed12);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_scale_pre(int Rm, int type, uint32_t shift, int W)
|
|
{
|
|
return mTarget->reg_scale_pre(Rm, type, shift, W);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_scale_post(int Rm, int type, uint32_t shift)
|
|
{
|
|
return mTarget->reg_scale_post(Rm, type, shift);
|
|
}
|
|
|
|
|
|
// LDRH/LDRSB/LDRSH/STRH
|
|
// (immediate and Rm can be negative, which indicates U=0)
|
|
uint32_t ARMAssemblerProxy::immed8_pre(int32_t immed8, int W)
|
|
{
|
|
return mTarget->immed8_pre(immed8, W);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::immed8_post(int32_t immed8)
|
|
{
|
|
return mTarget->immed8_post(immed8);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_pre(int Rm, int W)
|
|
{
|
|
return mTarget->reg_pre(Rm, W);
|
|
}
|
|
|
|
uint32_t ARMAssemblerProxy::reg_post(int Rm)
|
|
{
|
|
return mTarget->reg_post(Rm);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void ARMAssemblerProxy::dataProcessing( int opcode, int cc, int s,
|
|
int Rd, int Rn, uint32_t Op2)
|
|
{
|
|
mTarget->dataProcessing(opcode, cc, s, Rd, Rn, Op2);
|
|
}
|
|
|
|
void ARMAssemblerProxy::MLA(int cc, int s, int Rd, int Rm, int Rs, int Rn) {
|
|
mTarget->MLA(cc, s, Rd, Rm, Rs, Rn);
|
|
}
|
|
void ARMAssemblerProxy::MUL(int cc, int s, int Rd, int Rm, int Rs) {
|
|
mTarget->MUL(cc, s, Rd, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::UMULL(int cc, int s,
|
|
int RdLo, int RdHi, int Rm, int Rs) {
|
|
mTarget->UMULL(cc, s, RdLo, RdHi, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::UMUAL(int cc, int s,
|
|
int RdLo, int RdHi, int Rm, int Rs) {
|
|
mTarget->UMUAL(cc, s, RdLo, RdHi, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::SMULL(int cc, int s,
|
|
int RdLo, int RdHi, int Rm, int Rs) {
|
|
mTarget->SMULL(cc, s, RdLo, RdHi, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::SMUAL(int cc, int s,
|
|
int RdLo, int RdHi, int Rm, int Rs) {
|
|
mTarget->SMUAL(cc, s, RdLo, RdHi, Rm, Rs);
|
|
}
|
|
|
|
void ARMAssemblerProxy::B(int cc, uint32_t* pc) {
|
|
mTarget->B(cc, pc);
|
|
}
|
|
void ARMAssemblerProxy::BL(int cc, uint32_t* pc) {
|
|
mTarget->BL(cc, pc);
|
|
}
|
|
void ARMAssemblerProxy::BX(int cc, int Rn) {
|
|
mTarget->BX(cc, Rn);
|
|
}
|
|
void ARMAssemblerProxy::label(const char* theLabel) {
|
|
mTarget->label(theLabel);
|
|
}
|
|
void ARMAssemblerProxy::B(int cc, const char* label) {
|
|
mTarget->B(cc, label);
|
|
}
|
|
void ARMAssemblerProxy::BL(int cc, const char* label) {
|
|
mTarget->BL(cc, label);
|
|
}
|
|
|
|
uint32_t* ARMAssemblerProxy::pcForLabel(const char* label) {
|
|
return mTarget->pcForLabel(label);
|
|
}
|
|
|
|
void ARMAssemblerProxy::LDR(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->LDR(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::LDRB(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->LDRB(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::STR(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->STR(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::STRB(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->STRB(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::LDRH(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->LDRH(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::LDRSB(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->LDRSB(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::LDRSH(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->LDRSH(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::STRH(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->STRH(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::LDM(int cc, int dir, int Rn, int W, uint32_t reg_list) {
|
|
mTarget->LDM(cc, dir, Rn, W, reg_list);
|
|
}
|
|
void ARMAssemblerProxy::STM(int cc, int dir, int Rn, int W, uint32_t reg_list) {
|
|
mTarget->STM(cc, dir, Rn, W, reg_list);
|
|
}
|
|
|
|
void ARMAssemblerProxy::SWP(int cc, int Rn, int Rd, int Rm) {
|
|
mTarget->SWP(cc, Rn, Rd, Rm);
|
|
}
|
|
void ARMAssemblerProxy::SWPB(int cc, int Rn, int Rd, int Rm) {
|
|
mTarget->SWPB(cc, Rn, Rd, Rm);
|
|
}
|
|
void ARMAssemblerProxy::SWI(int cc, uint32_t comment) {
|
|
mTarget->SWI(cc, comment);
|
|
}
|
|
|
|
|
|
void ARMAssemblerProxy::PLD(int Rn, uint32_t offset) {
|
|
mTarget->PLD(Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::CLZ(int cc, int Rd, int Rm) {
|
|
mTarget->CLZ(cc, Rd, Rm);
|
|
}
|
|
void ARMAssemblerProxy::QADD(int cc, int Rd, int Rm, int Rn) {
|
|
mTarget->QADD(cc, Rd, Rm, Rn);
|
|
}
|
|
void ARMAssemblerProxy::QDADD(int cc, int Rd, int Rm, int Rn) {
|
|
mTarget->QDADD(cc, Rd, Rm, Rn);
|
|
}
|
|
void ARMAssemblerProxy::QSUB(int cc, int Rd, int Rm, int Rn) {
|
|
mTarget->QSUB(cc, Rd, Rm, Rn);
|
|
}
|
|
void ARMAssemblerProxy::QDSUB(int cc, int Rd, int Rm, int Rn) {
|
|
mTarget->QDSUB(cc, Rd, Rm, Rn);
|
|
}
|
|
void ARMAssemblerProxy::SMUL(int cc, int xy, int Rd, int Rm, int Rs) {
|
|
mTarget->SMUL(cc, xy, Rd, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::SMULW(int cc, int y, int Rd, int Rm, int Rs) {
|
|
mTarget->SMULW(cc, y, Rd, Rm, Rs);
|
|
}
|
|
void ARMAssemblerProxy::SMLA(int cc, int xy, int Rd, int Rm, int Rs, int Rn) {
|
|
mTarget->SMLA(cc, xy, Rd, Rm, Rs, Rn);
|
|
}
|
|
void ARMAssemblerProxy::SMLAL( int cc, int xy,
|
|
int RdHi, int RdLo, int Rs, int Rm) {
|
|
mTarget->SMLAL(cc, xy, RdHi, RdLo, Rs, Rm);
|
|
}
|
|
void ARMAssemblerProxy::SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn) {
|
|
mTarget->SMLAW(cc, y, Rd, Rm, Rs, Rn);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void ARMAssemblerProxy::ADDR_LDR(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->ADDR_LDR(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::ADDR_STR(int cc, int Rd, int Rn, uint32_t offset) {
|
|
mTarget->ADDR_STR(cc, Rd, Rn, offset);
|
|
}
|
|
void ARMAssemblerProxy::ADDR_ADD(int cc, int s, int Rd, int Rn, uint32_t Op2){
|
|
mTarget->ADDR_ADD(cc, s, Rd, Rn, Op2);
|
|
}
|
|
void ARMAssemblerProxy::ADDR_SUB(int cc, int s, int Rd, int Rn, uint32_t Op2){
|
|
mTarget->ADDR_SUB(cc, s, Rd, Rn, Op2);
|
|
}
|
|
|
|
}; // namespace android
|
|
|