1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/codeflinger/ARMAssemblerInterface.cpp 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License. 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdint.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/ARMAssemblerInterface.h" 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectARMAssemblerInterface::~ARMAssemblerInterface() 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ARMAssemblerInterface::buildImmediate( 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t immediate, uint32_t& rot, uint32_t& imm) 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rot = 0; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project imm = immediate; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (imm > 0x7F) { // skip the easy cases 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (!(imm&3) || (imm&0xFC000000)) { 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t newval; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project newval = imm >> 2; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project newval |= (imm&3) << 30; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project imm = newval; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rot += 2; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rot == 32) { 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rot = 0; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rot = (16 - (rot>>1)) & 0xF; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (imm>=0x100) 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -EINVAL; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// shifters... 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbool ARMAssemblerInterface::isValidImmediate(uint32_t immediate) 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t rot, imm; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buildImmediate(immediate, rot, imm) == 0; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::imm(uint32_t immediate) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t rot, imm; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err = buildImmediate(immediate, rot, imm); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(err==-EINVAL, 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "immediate %08x cannot be encoded", 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immediate); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(err, 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "immediate (%08x) encoding bogus!", 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immediate); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<25) | (rot<<8) | imm; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_imm(int Rm, int type, uint32_t shift) 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_rrx(int Rm) 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (ROR<<5) | (Rm&0xF); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_reg(int Rm, int type, int Rs) 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// addressing modes... 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "LDR(B)/STR(B)/PLD immediate too big (%08x)", 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immed12); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<24) | (((uint32_t(immed12)>>31)^1)<<23) | 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((W&1)<<21) | (abs(immed12)&0x7FF); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::immed12_post(int32_t immed12) 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "LDR(B)/STR(B)/PLD immediate too big (%08x)", 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immed12); 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_scale_pre(int Rm, int type, 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t shift, int W) 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<25) | (1<<24) | 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg_imm(abs(Rm), type, shift); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_scale_post(int Rm, int type, uint32_t shift) 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t offset = abs(immed8); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immed8); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<24) | (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::immed8_post(int32_t immed8) 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t offset = abs(immed8); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immed8); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (((offset&0xF0)<<4) | (offset&0xF)); 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_pre(int Rm, int W) 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ARMAssemblerInterface::reg_post(int Rm) 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174