⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jitemitter_cpu.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * @(#)jitemitter_cpu.c	1.263 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * *//* * ARM-specific bits. * Does not use compiler context, yet. */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/utils.h"#include "javavm/include/globals.h"#include "javavm/include/interpreter.h"#include "javavm/include/ccm_runtime.h"#include "javavm/include/ccee.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitutils.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitirnode.h"#include "portlibs/jit/risc/include/porting/jitriscemitter.h"#include "portlibs/jit/risc/include/porting/ccmrisc.h"#include "portlibs/jit/risc/include/export/jitregman.h"#include "javavm/include/jit/jitconstantpool.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitintrinsic.h"#include "javavm/include/jit/jitpcmap.h"#include "javavm/include/jit/jitfixup.h"#include "javavm/include/porting/endianness.h"#include "javavm/include/porting/doubleword.h"#include "javavm/include/porting/jit/jit.h"#include "javavm/include/clib.h"/* * Macros for 64-bit access. */#if CVM_ENDIANNESS == CVM_BIG_ENDIAN#define HIREG(reg)  (reg)#define LOREG(reg)  (reg)+1#elif CVM_ENDIANNESS == CVM_LITTLE_ENDIAN#define HIREG(reg)  (reg)+1#define LOREG(reg)  (reg)#endifstatic voidCVMARMemitCompareConditional(CVMJITCompilationContext* con, int opcode,                             int lhsRegID, CVMCPUALURhsToken rhsToken,                             CVMCPUCondCode condCode);/************************************************************** * CPU ALURhs and associated types - The following are implementations * of the functions for the ALURhs abstraction required by the RISC * emitter porting layer. **************************************************************//* ALURhs constructors and query APIs: ==================================== *//* Purpose: Constructs a constant type CVMCPUALURhs. */CVMCPUALURhs*CVMCPUalurhsNewConstant(CVMJITCompilationContext* con, CVMInt32 v){    CVMCPUALURhs* ap = CVMJITmemNew(con, JIT_ALLOC_CGEN_ALURHS,                                    sizeof(CVMCPUALURhs));    ap->type = CVMARM_ALURHS_CONSTANT;    ap->constValue = v;    return ap;}/* Purpose: Constructs an ALURhs to represent a register shifted by a            constant. */CVMCPUALURhs*CVMARMalurhsNewShiftByConstant(    CVMJITCompilationContext* con,    int shiftOp,    CVMRMResource* reg,    CVMInt32 shiftval){    CVMCPUALURhs* ap = CVMJITmemNew(con, JIT_ALLOC_CGEN_ALURHS,                                    sizeof(CVMCPUALURhs));    ap->type = CVMARM_ALURHS_SHIFT_BY_CONSTANT;    ap->shiftOp = shiftOp;    ap->constValue = shiftval;    ap->r1 = reg;    return ap;}/* Purpose: Constructs an ALURhs to represent a register shifted by another            register. */CVMCPUALURhs*CVMARMalurhsNewShiftByReg(    CVMJITCompilationContext* con,    int shiftOp,    CVMRMResource* reg,    CVMRMResource* shiftval){    CVMCPUALURhs* ap = CVMJITmemNew(con, JIT_ALLOC_CGEN_ALURHS,                                    sizeof(CVMCPUALURhs));    ap->type = CVMARM_ALURHS_SHIFT_BY_REGISTER;    ap->shiftOp = shiftOp;    ap->r1 = reg;    ap->r2 = shiftval;    return ap;}/* ALURhs token encoder APIs: ============================================= */#define CVMARMalurhsEncodeLargeConstantToken(base, rotate) \    (CVMARM_MODE1_CONSTANT | (rotate << 8) | base)/* Purpose: Encodes the token for the CVMCPUALURhs operand for use in the            instruction emitters. */CVMCPUALURhsTokenCVMARMalurhsEncodeToken(CVMJITCompilationContext* con,			CVMARMALURhsType type, int constValue,                        int shiftOp, int r1RegID, int r2RegID){   CVMJITcsPushSourceRegister(con, r1RegID);    switch(type){    case CVMARM_ALURHS_CONSTANT: {        CVMUint32 base;        CVMUint32 rotate;        CVMBool success;        success = CVMARMmode1EncodeImmediate(constValue, &base, &rotate);        CVMassert(success);        return CVMARM_MODE1_CONSTANT | (rotate << 8) | base;    }    case CVMARM_ALURHS_SHIFT_BY_CONSTANT: {        /* Currently, CVMARM_ALURHS_SHIFT_BY_CONSTANT is only used for           implementing the Java shift operators.  Hence, the shift offsets           must be between 0 and 31 (and were masked with 0x1f before getting           here).           NOTE: For CVMCPU_SRL_OPCODE and CVMCPU_SRA_OPCODE, a shiftOffset of           32 is encoded as 0.  Hence, if the shiftOffset is meant to be 0,           then the shiftop will have to be set to CVMCPU_SLL_OPCODE which           essentially does nothing as expected.        */        CVMassert((constValue >= 0) && (constValue <= 31));        shiftOp = (constValue == 0) ? CVMCPU_SLL_OPCODE : shiftOp;        return CVMARM_MODE1_SHIFT_CONSTANT | r1RegID | shiftOp |               constValue << 7;    }    case CVMARM_ALURHS_SHIFT_BY_REGISTER:        CVMJITcsPushSourceRegister(con, r2RegID);        return CVMARM_MODE1_SHIFT_REGISTER | r1RegID | shiftOp | r2RegID << 8;    default:	CVMassert(CVM_FALSE);	return 0;    }}/* Purpose: Gets the token for the CVMCPUALURhs operand for use in the            instruction emitters. */CVMCPUALURhsTokenCVMARMalurhsGetToken(CVMJITCompilationContext* con, const CVMCPUALURhs *aluRhs){    CVMCPUALURhsToken result;    int r1RegID = CVMCPU_INVALID_REG;    int r2RegID = CVMCPU_INVALID_REG;    if (aluRhs->type == CVMARM_ALURHS_SHIFT_BY_CONSTANT) {        r1RegID = CVMRMgetRegisterNumber(aluRhs->r1);    } else if (aluRhs->type == CVMARM_ALURHS_SHIFT_BY_REGISTER) {        r1RegID = CVMRMgetRegisterNumber(aluRhs->r1);        r2RegID = CVMRMgetRegisterNumber(aluRhs->r2);    }    result = CVMARMalurhsEncodeToken(con, aluRhs->type, aluRhs->constValue,                                     aluRhs->shiftOp, r1RegID, r2RegID);    return result;}/* ALURhs resource management APIs: ======================================= *//* Purpose: Pins the resources that this CVMCPUALURhs may use. */voidCVMCPUalurhsPinResource(CVMJITRMContext* con, int opcode, CVMCPUALURhs* ap,                        CVMRMregset target, CVMRMregset avoid){    switch (ap->type){    case CVMARM_ALURHS_CONSTANT:        /* If we can't encode the constant as an immediate, then load it into           a register and re-write the aluRhs as a           CVMARM_ALURHS_SHIFT_BY_CONSTANT: */        if (!CVMCPUalurhsIsEncodableAsImmediate(opcode, ap->constValue)) {            ap->type = CVMARM_ALURHS_SHIFT_BY_CONSTANT;            ap->shiftOp = CVMARM_NOSHIFT_OPCODE;            ap->r1 = CVMRMgetResourceForConstant32(con, target, avoid,                                                   ap->constValue);            ap->constValue = 0;        }	return;    case CVMARM_ALURHS_SHIFT_BY_CONSTANT:        CVMRMpinResource(con, ap->r1, target, avoid);	return;    case CVMARM_ALURHS_SHIFT_BY_REGISTER:        CVMRMpinResource(con, ap->r1, target, avoid);        CVMRMpinResource(con, ap->r2, target, avoid);	return;    }}/* Purpose: Relinquishes the resources that this CVMCPUALURhsToken may use. */voidCVMCPUalurhsRelinquishResource(CVMJITRMContext* con,                               CVMCPUALURhs* ap){    switch (ap->type){    case CVMARM_ALURHS_CONSTANT:	break;    case CVMARM_ALURHS_SHIFT_BY_CONSTANT:        CVMRMrelinquishResource(con, ap->r1);	break;    case CVMARM_ALURHS_SHIFT_BY_REGISTER:        CVMRMrelinquishResource(con, ap->r1);        CVMRMrelinquishResource(con, ap->r2);	break;    }    /* Will be freed whole-sale at the very end       free(ap); */}/* MemSpec constructors and query APIs: =================================== *//* Purpose: Constructs a CVMCPUMemSpec immediate operand. */CVMCPUMemSpec *CVMCPUmemspecNewImmediate(CVMJITCompilationContext *con, CVMInt32 value){    CVMCPUMemSpec *mp;    mp = CVMJITmemNew(con, JIT_ALLOC_CGEN_MEMSPEC, sizeof(CVMCPUMemSpec));    mp->type = CVMCPU_MEMSPEC_IMMEDIATE_OFFSET;    mp->offsetValue = value;    mp->offsetReg = NULL;    mp->shiftOpcode = CVMARM_NOSHIFT_OPCODE;    mp->shiftAmount = 0;    return mp;}/* Purpose: Constructs a MemSpec register operand. */CVMCPUMemSpec *CVMCPUmemspecNewRegister(CVMJITCompilationContext *con,                         CVMBool offsetIsToBeAdded, CVMRMResource *offsetReg){    CVMCPUMemSpec *mp;    mp = CVMJITmemNew(con, JIT_ALLOC_CGEN_MEMSPEC, sizeof(CVMCPUMemSpec));    mp->type = CVMCPU_MEMSPEC_REG_OFFSET;    mp->offsetValue = 0;    mp->offsetReg = offsetReg;    mp->shiftOpcode = CVMARM_NOSHIFT_OPCODE;    mp->shiftAmount = 0;    return mp;}/* MemSpec token encoder APIs: ============================================ */#define CVMARMmemspecGetTokenType(memSpecToken) \    ((memSpecToken) & 0xff)#define CVMARMmemspecGetTokenOffset(memSpecToken) \    ((CVMInt32)((CVMInt16)(((memSpecToken) >> 16) & 0xffff)))#define CVMARMmemspecGetTokenShiftOpcode(memSpecToken) \    (((memSpecToken) >> 8) & 0x60)#define CVMARMmemspecGetTokenShiftAmount(memSpecToken) \    (((memSpecToken) >> 8) & 0x1f)/* Purpose: Encodes a CVMCPUMemSpecToken from the specified memSpec. */CVMCPUMemSpecTokenCVMARMmemspecGetToken(CVMJITCompilationContext *con,		      const CVMCPUMemSpec *memSpec){    CVMCPUMemSpecToken token;    int type = memSpec->type;    int offset;    int shiftOp = memSpec->shiftOpcode;    int shiftImm = memSpec->shiftAmount;    offset = (type == CVMCPU_MEMSPEC_REG_OFFSET) ?              CVMRMgetRegisterNumber(memSpec->offsetReg) :              memSpec->offsetValue;    token = CVMARMmemspecEncodeToken(type, offset, shiftOp, shiftImm);    return token;}/* MemSpec resource management APIs: ====================================== *//* Purpose: Pins the resources that this CVMCPUMemSpec may use. */voidCVMCPUmemspecPinResource(CVMJITRMContext *con, CVMCPUMemSpec *self,                         CVMRMregset target, CVMRMregset avoid){    switch (self->type) {    case CVMCPU_MEMSPEC_IMMEDIATE_OFFSET:        /* If we can't encode the constant as an immediate, then load it into           a register and re-write the memSpec as a           CVMCPU_MEMSPEC_REG_OFFSET: */        if (!CVMCPUmemspecIsEncodableAsImmediate(self->offsetValue)) {            self->type = CVMCPU_MEMSPEC_REG_OFFSET;            self->offsetReg =                CVMRMgetResourceForConstant32(con, target, avoid,                                              self->offsetValue);            self->offsetValue = 0;            self->shiftOpcode = CVMARM_NOSHIFT_OPCODE;            self->shiftAmount = 0;        }        return;    case CVMCPU_MEMSPEC_REG_OFFSET:        CVMRMpinResource(con, self->offsetReg, target, avoid);        return;    default:        /* No pinning needed for the other memSpec types. */        /* Since the post-increment and pre-decrement types are only used           for pushing and popping arguments on to the Java stack, the           immediate offset should always be small.  No need to check if           it is encodable: */        CVMassert(CVMCPUmemspecIsEncodableAsImmediate(self->offsetValue));    }}/* Purpose: Relinquishes the resources that this CVMCPUMemSpec may use. */voidCVMCPUmemspecRelinquishResource(CVMJITRMContext *con,                                CVMCPUMemSpec *self){    switch (self->type) {    case CVMCPU_MEMSPEC_REG_OFFSET:        CVMRMrelinquishResource(con, self->offsetReg);        break;    default:        ; /* No unpinning needed for the other memSpec types. */    }}/************************************************************** * CPU code emitters - The following are implementations of code * emitters required by the RISC emitter porting layer. **************************************************************//* Private ARM specific defintions: ======================================= */#define ARM_MVN_OPCODE (0x1e << 20)#define ARM_ADC_OPCODE (0x0a << 20) /* needed for ADD64 codegen comments */#define ARM_SBC_OPCODE (0x0c << 20) /* needed for SUB64 codegen comments */#define ARM_RSB_OPCODE CVMARM_RSB_OPCODE#define ARM_RSC_OPCODE (0x0e << 20)#define ARM_UMULL_OPCODE 0x00800090  /* reg32hi,reg32lo = reg32 * reg32.*//* Flow control opcodes: */#define ARM_B_OPCODE                (5 << 25)   /* branch. */#define ARM_BL_OPCODE               (ARM_B_OPCODE | (1 << 24)) /* b and link.*/#ifdef CVM_MP_SAFE#define ARM_LDREX_OPCODE (0x01900f9f)#define ARM_STREX_OPCODE (0x01800f90)#define ARM_MCR_OPCODE (0x0e000000)#define C7 7#define C10 10#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -