dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/engine md_arm.c, NONE, 1.1 md_x86.c, NO


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/engine md_arm.c, NONE, 1.1 md_x86.c, NONE, 1.1 unroll_arith.c, NONE, 1.1 md_arm.h, 1.1, 1.2 md_default.h, 1.1, 1.2 md_x86.h, 1.1, 1.2 unroll.c, 1.1, 1.2
Date: Thu, 10 Jul 2003 03:28:20 -0400

Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv16685/engine

Modified Files:
        md_arm.h md_default.h md_x86.h unroll.c 
Added Files:
        md_arm.c md_x86.c unroll_arith.c 
Log Message:


Add some more code to the generic unroller.


--- NEW FILE ---
/*
 * md_arm.c - Machine-dependent definitions for ARM.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "md_arm.h"

#ifdef  __cplusplus
extern  "C" {
#endif

arm_inst_ptr _arm_mov_reg_imm(arm_inst_ptr inst, int reg, int value)
{
        /* Handle bytes in various positions */
        if((value & 0x000000FF) == value)
        {
                arm_mov_reg_imm8(inst, reg, value);
                return inst;
        }
        else if((value & 0x0000FF00) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
                return inst;
        }
        else if((value & 0x00FF0000) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
                return inst;
        }
        else if((value & 0xFF000000) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
                return inst;
        }

        /* Handle inverted bytes in various positions */
        value = ~value;
        if((value & 0x000000FF) == value)
        {
                arm_mov_reg_imm8(inst, reg, value);
                arm_alu_reg(inst, ARM_MVN, reg, reg);
                return inst;
        }
        else if((value & 0x0000FF00) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
                arm_alu_reg(inst, ARM_MVN, reg, reg);
                return inst;
        }
        else if((value & 0x00FF0000) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
                arm_alu_reg(inst, ARM_MVN, reg, reg);
                return inst;
        }
        else if((value & 0xFF000000) == value)
        {
                arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
                arm_alu_reg(inst, ARM_MVN, reg, reg);
                return inst;
        }

        /* Build the value the hard way, byte by byte */
        value = ~value;
        if((value & 0xFF000000) != 0)
        {
                arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
                if((value & 0x00FF0000) != 0)
                {
                        arm_alu_reg_imm8_rotate
                                (inst, ARM_ADD, reg, reg, ((value >> 16) & 
0xFF), 8);
                }
                if((value & 0x0000FF00) != 0)
                {
                        arm_alu_reg_imm8_rotate
                                (inst, ARM_ADD, reg, reg, ((value >> 8) & 
0xFF), 12);
                }
                if((value & 0x000000FF) != 0)
                {
                        arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
                }
        }
        else if((value & 0x00FF0000) != 0)
        {
                arm_mov_reg_imm8_rotate(inst, reg, ((value >> 16) & 0xFF), 8);
                if((value & 0x0000FF00) != 0)
                {
                        arm_alu_reg_imm8_rotate
                                (inst, ARM_ADD, reg, reg, ((value >> 8) & 
0xFF), 12);
                }
                if((value & 0x000000FF) != 0)
                {
                        arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
                }
        }
        else if((value & 0x0000FF00) != 0)
        {
                arm_mov_reg_imm8_rotate(inst, reg, ((value >> 8) & 0xFF), 12);
                if((value & 0x000000FF) != 0)
                {
                        arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
                }
        }
        else
        {
                arm_mov_reg_imm8(inst, reg, (value & 0xFF));
        }
        return inst;
}

arm_inst_ptr _arm_alu_reg_imm(arm_inst_ptr inst, int opc,
                                                  int dreg, int sreg, int imm,
                                                  int saveWork)
{
        int tempreg;
        if(saveWork)
        {
                if(dreg != ARM_R2 && sreg != ARM_R2)
                {
                        tempreg = ARM_R2;
                }
                else if(dreg != ARM_R3 && sreg != ARM_R3)
                {
                        tempreg = ARM_R3;
                }
                else
                {
                        tempreg = ARM_R4;
                }
                arm_push_reg(inst, tempreg);
        }
        else
        {
                tempreg = ARM_WORK;
        }
        _arm_mov_reg_imm(inst, tempreg, imm);
        arm_alu_reg_reg(inst, opc, dreg, sreg, tempreg);
        if(saveWork)
        {
                arm_pop_reg(inst, tempreg);
        }
        return inst;
}

md_inst_ptr _md_arm_setcc(md_inst_ptr inst, int reg, int cond, int invcond)
{
        arm_test_reg_imm8(inst, ARM_CMP, reg, 0);
        arm_alu_reg_imm8_cond(inst, ARM_MOV, reg, 0, 1, cond);
        arm_alu_reg_imm8_cond(inst, ARM_MOV, reg, 0, 0, invcond);
        return inst;
}

#ifdef  __cplusplus
};
#endif

--- NEW FILE ---
/*
 * md_x86.c - Machine-dependent definitions for x86.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "md_x86.h"

#ifdef  __cplusplus
extern  "C" {
#endif

md_inst_ptr _md_x86_shift(md_inst_ptr inst, int opc, int reg1, int reg2)
{
        if(reg2 == X86_ECX)
        {
                /* The shift value is already in ECX */
                x86_shift_reg(inst, opc, reg1);
        }
        else if(reg1 == X86_ECX)
        {
                /* The value to be shifted is in ECX, so swap the order */
                x86_xchg_reg_reg(inst, reg1, reg2, 4);
                x86_shift_reg(inst, opc, reg2);
                x86_mov_reg_reg(inst, reg1, reg2, 4);
        }
        else
        {
                /* Save ECX, perform the shift, and then restore ECX */
                x86_push_reg(inst, X86_ECX);
                x86_mov_reg_reg(inst, X86_ECX, reg2, 4);
                x86_shift_reg(inst, opc, reg1);
                x86_pop_reg(inst, X86_ECX);
        }
        return inst;
}

md_inst_ptr _md_x86_mov_membase_reg_byte
                        (md_inst_ptr inst, int basereg, int offset, int srcreg)
{
        if(srcreg == X86_EAX || srcreg == X86_EBX ||
           srcreg == X86_ECX || srcreg == X86_EDX)
        {
                x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
        }
        else if(basereg != X86_EAX)
        {
                x86_push_reg(inst, X86_EAX);
                x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
                x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
                x86_pop_reg(inst, X86_EAX);
        }
        else
        {
                x86_push_reg(inst, X86_EDX);
                x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
                x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
                x86_pop_reg(inst, X86_EDX);
        }
        return inst;
}

md_inst_ptr _md_x86_rem_float
                (md_inst_ptr inst, int reg1, int reg2, int used)
{
        md_inst_ptr label;
        if((used & (1 << X86_EAX)) != 0)
        {
                x86_push_reg(inst, X86_EAX);
        }
        label = inst;
        x86_fprem1(inst);
        x86_fnstsw(inst);
        x86_alu_reg_imm(inst, X86_AND, X86_EAX, 0x0400);
        x86_branch(inst, X86_CC_NZ, label, 0);
        x86_fstp(inst, 1);
        if((used & (1 << X86_EAX)) != 0)
        {
                x86_pop_reg(inst, X86_EAX);
        }
        return inst;
}

md_inst_ptr _md_x86_setcc(md_inst_ptr inst, int reg, int cond)
{
        if(cond == X86_CC_EQ || cond == X86_CC_NE)
        {
                x86_alu_reg_reg(inst, X86_OR, reg, reg);
        }
        else
        {
                x86_alu_reg_imm(inst, X86_CMP, reg, 0);
        }
        if(reg == X86_EAX || reg == X86_EBX || reg == X86_ECX || reg == X86_EDX)
        {
                /* Use a SETcc instruction if we have a basic register */
                x86_set_reg(inst, cond, reg, 1);
                x86_widen_reg(inst, reg, reg, 0, 0);
        }
        else
        {
                /* The register is not useable as an 8-bit destination */
                unsigned char *patch1, *patch2;
                patch1 = inst;
                x86_branch8(inst, cond, 0, 1);
                x86_clear_reg(inst, reg);
                patch2 = inst;
                x86_jump8(inst, 0);
                x86_patch(patch1, inst);
                x86_mov_reg_imm(inst, reg, 1);
                x86_patch(patch2, inst);
        }
        return inst;
}

md_inst_ptr _md_x86_compare(md_inst_ptr inst, int reg1, int reg2, int isSigned)
{
        unsigned char *patch1, *patch2, *patch3;
        x86_alu_reg_reg(inst, X86_CMP, reg1, reg2);
        patch1 = inst;
        x86_branch8(inst, X86_CC_GE, 0, isSigned);
        x86_mov_reg_imm(inst, reg1, -1);
        patch2 = inst;
        x86_jump8(inst, 0);
        x86_patch(patch1, inst);
        patch1 = inst;
        x86_branch8(inst, X86_CC_EQ, 0, 0);
        x86_mov_reg_imm(inst, reg1, 1);
        patch3 = inst;
        x86_jump8(inst, 0);
        x86_patch(patch1, inst);
        x86_clear_reg(inst, reg1);
        x86_patch(patch2, inst);
        x86_patch(patch3, inst);
        return inst;
}

#ifdef  __cplusplus
};
#endif

--- NEW FILE ---
/*
 * unroll_arith.c - Arithmetic handling for generic CVM unrolling.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef IL_UNROLL_GLOBAL

#ifdef CVM_X86

/*
 * Perform an integer division or remainder.
 */
static void X86Divide(MDUnroll *unroll, int isSigned, int wantRemainder,
                                      unsigned char *pc, unsigned char *label)
{
        unsigned char *patch1, *patch2, *patch3;

        /* Get the arguments into EAX and ECX so we know where they are */
        if(unroll->pseudoStackSize != 2 ||
           unroll->pseudoStack[0] != X86_EAX ||
           unroll->pseudoStack[1] != X86_ECX)
        {
                FlushRegisterStack(unroll);
                unroll->stackHeight -= 8;
                x86_mov_reg_membase(unroll->out, X86_EAX, MD_REG_STACK,
                                                        unroll->stackHeight, 4);
                x86_mov_reg_membase(unroll->out, X86_ECX, MD_REG_STACK,
                                                        unroll->stackHeight + 
4, 4);
                unroll->pseudoStack[0] = X86_EAX;
                unroll->pseudoStack[1] = X86_ECX;
                unroll->pseudoStackSize = 2;
                unroll->regsUsed |= ((1 << X86_EAX) | (1 << X86_ECX));
        }

        /* Check for conditions that may cause an exception */
        x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, 0);
        patch1 = unroll->out;
        x86_branch8(unroll->out, X86_CC_EQ, 0, 0);
        x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, -1);
        patch2 = unroll->out;
        x86_branch32(unroll->out, X86_CC_NE, 0, 0);
        x86_alu_reg_imm(unroll->out, X86_CMP, X86_EAX, (int)0x80000000);
        patch3 = unroll->out;
        x86_branch32(unroll->out, X86_CC_NE, 0, 0);
        x86_patch(patch1, unroll->out);

        /* Re-execute the division instruction to throw the exception */
        ReExecute(unroll, pc, label);

        /* Perform the division */
        x86_patch(patch2, unroll->out);
        x86_patch(patch3, unroll->out);
        if(isSigned)
        {
                x86_cdq(unroll->out);
        }
        else
        {
                x86_clear_reg(unroll->out, X86_EDX);
        }
        x86_div_reg(unroll->out, X86_ECX, isSigned);

        /* Pop ECX from the pseudo stack */
        FreeTopRegister(unroll, -1);

        /* If we want the remainder, then replace EAX with EDX on the stack */
        if(wantRemainder)
        {
                unroll->pseudoStack[0] = X86_EDX;
                unroll->regsUsed = (1 << X86_EDX);
        }
}

#endif /* CVM_X86 */

#elif defined(IL_UNROLL_CASES)

case COP_IADD:
{
        /* Add integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_add_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_ISUB:
{
        /* Subtract integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_sub_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IMUL:
{
        /* Multiply integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_mul_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef CVM_X86

case COP_IDIV:
{
        /* Divide integers */
        UNROLL_START();
        X86Divide(&unroll, 1, 0, pc, (unsigned char *)inst);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IDIV_UN:
{
        /* Divide unsigned integers */
        UNROLL_START();
        X86Divide(&unroll, 0, 0, pc, (unsigned char *)inst);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IREM:
{
        /* Remainder integers */
        UNROLL_START();
        X86Divide(&unroll, 1, 1, pc, (unsigned char *)inst);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IREM_UN:
{
        /* Remainder unsigned integers */
        UNROLL_START();
        X86Divide(&unroll, 0, 1, pc, (unsigned char *)inst);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* CVM_X86 */

case COP_INEG:
{
        /* Negate integer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_neg_reg_word_32(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef MD_HAS_FP

case COP_FADD:
{
        /* Add floating point */
        UNROLL_START();
        GetTopTwoFPRegisters(&unroll, &reg, &reg2, 0);
        md_add_reg_reg_float(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_FSUB:
{
        /* Subtract floating point */
        UNROLL_START();
        GetTopTwoFPRegisters(&unroll, &reg, &reg2, 0);
        md_sub_reg_reg_float(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_FMUL:
{
        /* Multiply floating point */
        UNROLL_START();
        GetTopTwoFPRegisters(&unroll, &reg, &reg2, 0);
        md_mul_reg_reg_float(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_FDIV:
{
        /* Divide floating point */
        UNROLL_START();
        GetTopTwoFPRegisters(&unroll, &reg, &reg2, 0);
        md_div_reg_reg_float(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_FREM:
{
        /* Remainder floating point */
        UNROLL_START();
        GetTopTwoFPRegisters(&unroll, &reg, &reg2, 1);
        md_rem_reg_reg_float(unroll.out, reg, reg2, unroll.regsUsed);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_FNEG:
{
        /* Negate floating point */
        UNROLL_START();
        reg = GetTopFPRegister(&unroll);
        md_neg_reg_float(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* MD_HAS_FP */

case COP_IAND:
{
        /* Bitwise and integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_and_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IOR:
{
        /* Bitwise or integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_or_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IXOR:
{
        /* Bitwise xor integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_xor_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_INOT:
{
        /* Bitwise not integer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_not_reg_word_32(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_ISHL:
{
        /* Left shift integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_shl_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_ISHR:
{
        /* Right shift integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_shr_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_ISHR_UN:
{
        /* Unsigned right shift integers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_ushr_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_ICMP:
{
        /* Compare integer values with -1, 0, or 1 result */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_ICMP_UN:
{
        /* Compare unsigned integer values with -1, 0, or 1 result */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2, MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_ucmp_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_PCMP:
{
        /* Compare native word values with -1, 0, or 1 result */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_ucmp_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETEQ:
{
        /* Set if top of stack is equal to zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_seteq_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETNE:
{
        /* Set if top of stack is not equal to zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_setne_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETLT:
{
        /* Set if top of stack is less than zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_setlt_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETLE:
{
        /* Set if top of stack is less than or equal to zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_setle_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETGT:
{
        /* Set if top of stack is greater than zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_setgt_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SETGE:
{
        /* Set if top of stack is greater than or equal to zero */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_setge_reg(unroll.out, reg);
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

#endif /* IL_UNROLL_CASES */

Index: md_arm.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_arm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_arm.h    14 May 2003 06:17:12 -0000      1.1
--- md_arm.h    10 Jul 2003 07:28:17 -0000      1.2
***************
*** 388,529 ****
  
  /*
!  * Helper routine for the complex cases of "arm_mov_reg_imm".
!  * TODO: make this static.
   */
! arm_inst_ptr _arm_mov_reg_imm(arm_inst_ptr inst, int reg, int value)
! {
!       /* Handle bytes in various positions */
!       if((value & 0x000000FF) == value)
!       {
!               arm_mov_reg_imm8(inst, reg, value);
!               return inst;
!       }
!       else if((value & 0x0000FF00) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
!               return inst;
!       }
!       else if((value & 0x00FF0000) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
!               return inst;
!       }
!       else if((value & 0xFF000000) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
!               return inst;
!       }
! 
!       /* Handle inverted bytes in various positions */
!       value = ~value;
!       if((value & 0x000000FF) == value)
!       {
!               arm_mov_reg_imm8(inst, reg, value);
!               arm_alu_reg(inst, ARM_MVN, reg, reg);
!               return inst;
!       }
!       else if((value & 0x0000FF00) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
!               arm_alu_reg(inst, ARM_MVN, reg, reg);
!               return inst;
!       }
!       else if((value & 0x00FF0000) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
!               arm_alu_reg(inst, ARM_MVN, reg, reg);
!               return inst;
!       }
!       else if((value & 0xFF000000) == value)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
!               arm_alu_reg(inst, ARM_MVN, reg, reg);
!               return inst;
!       }
! 
!       /* Build the value the hard way, byte by byte */
!       value = ~value;
!       if((value & 0xFF000000) != 0)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
!               if((value & 0x00FF0000) != 0)
!               {
!                       arm_alu_reg_imm8_rotate
!                               (inst, ARM_ADD, reg, reg, ((value >> 16) & 
0xFF), 8);
!               }
!               if((value & 0x0000FF00) != 0)
!               {
!                       arm_alu_reg_imm8_rotate
!                               (inst, ARM_ADD, reg, reg, ((value >> 8) & 
0xFF), 12);
!               }
!               if((value & 0x000000FF) != 0)
!               {
!                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
!               }
!       }
!       else if((value & 0x00FF0000) != 0)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 16) & 0xFF), 8);
!               if((value & 0x0000FF00) != 0)
!               {
!                       arm_alu_reg_imm8_rotate
!                               (inst, ARM_ADD, reg, reg, ((value >> 8) & 
0xFF), 12);
!               }
!               if((value & 0x000000FF) != 0)
!               {
!                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
!               }
!       }
!       else if((value & 0x0000FF00) != 0)
!       {
!               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 8) & 0xFF), 12);
!               if((value & 0x000000FF) != 0)
!               {
!                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 
0xFF));
!               }
!       }
!       else
!       {
!               arm_mov_reg_imm8(inst, reg, (value & 0xFF));
!       }
!       return inst;
! }
  
  /*
!  * Helper routine for the complex cases of "arm_alu_reg_imm".
   */
! arm_inst_ptr _arm_alu_reg_imm(arm_inst_ptr inst, int opc,
!                                                 int dreg, int sreg, int imm,
!                                                 int saveWork)
! {
!       int tempreg;
!       if(saveWork)
!       {
!               if(dreg != ARM_R2 && sreg != ARM_R2)
!               {
!                       tempreg = ARM_R2;
!               }
!               else if(dreg != ARM_R3 && sreg != ARM_R3)
!               {
!                       tempreg = ARM_R3;
!               }
!               else
!               {
!                       tempreg = ARM_R4;
!               }
!               arm_push_reg(inst, tempreg);
!       }
!       else
!       {
!               tempreg = ARM_WORK;
!       }
!       _arm_mov_reg_imm(inst, tempreg, imm);
!       arm_alu_reg_reg(inst, opc, dreg, sreg, tempreg);
!       if(saveWork)
!       {
!               arm_pop_reg(inst, tempreg);
!       }
!       return inst;
! }
  
  #ifdef        __cplusplus
--- 388,434 ----
  
  /*
!  * Set a register to a 0 or 1 value based on a condition.
   */
! extern md_inst_ptr _md_arm_setcc(md_inst_ptr inst, int reg,
!                                                                int cond, int 
invcond);
! #define       md_seteq_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_EQ, ARM_CC_NE); 
} while (0)
! #define       md_setne_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_NE, ARM_CC_EQ); 
} while (0)
! #define       md_setlt_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_LT, ARM_CC_GE); 
} while (0)
! #define       md_setle_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_LE, ARM_CC_GT); 
} while (0)
! #define       md_setgt_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_GT, ARM_CC_LE); 
} while (0)
! #define       md_setge_reg(inst,reg)  \
!                       do { (inst) = _md_arm_setcc \
!                                       ((inst), (reg), ARM_CC_GE, ARM_CC_LT); 
} while (0)
  
  /*
!  * Set a register to -1, 0, or 1 based on comparing two values.
   */
! #define       md_cmp_reg_reg_word_32(inst,reg1,reg2)  \
!                       do { \
!                               arm_test_reg_reg((inst), ARM_CMP, reg1, reg2); \
!                               arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0, 
1, ARM_CC_GT); \
!                               arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0, 
0, ARM_CC_LE); \
!                               arm_alu_reg_cond((inst), ARM_MVN, reg1, reg1, 
ARM_CC_LT); \
!                       } while (0)
! #define       md_ucmp_reg_reg_word_32(inst,reg1,reg2) \
!                       do { \
!                               arm_test_reg_reg((inst), ARM_CMP, reg1, reg2); \
!                               arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0, 
1, \
!                                                                         
ARM_CC_GT_UN); \
!                               arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0, 
0, \
!                                                                         
ARM_CC_LE_UN); \
!                               arm_alu_reg_cond((inst), ARM_MVN, reg1, reg1, \
!                                                                ARM_CC_LT_UN); 
\
!                       } while (0)
  
  #ifdef        __cplusplus

Index: md_default.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_default.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_default.h        14 May 2003 06:17:12 -0000      1.1
--- md_default.h        10 Jul 2003 07:28:17 -0000      1.2
***************
*** 75,82 ****
  #define       md_div_reg_reg_float(inst,reg1,reg2)    \
                        do { ; } while (0)
! #define       md_rem_reg_reg_float(inst,reg1,reg2)    \
                        do { ; } while (0)
  #define       md_neg_reg_float(inst,reg)      \
                        do { ; } while (0)
  #endif
  
--- 75,92 ----
  #define       md_div_reg_reg_float(inst,reg1,reg2)    \
                        do { ; } while (0)
! #define       md_rem_reg_reg_float(inst,reg1,reg2,used)       \
                        do { ; } while (0)
  #define       md_neg_reg_float(inst,reg)      \
                        do { ; } while (0)
+ #endif
+ 
+ /*
+  * Set a register to -1, 0, or 1 based on comparing two values.
+  */
+ #if defined(IL_NATIVE_INT32) && !defined(md_cmp_reg_reg_word_native)
+ #define       md_cmp_reg_reg_word_native(inst,reg1,reg2)      \
+                       md_cmp_reg_reg_word_32((inst), (reg1), (reg2))
+ #define       md_ucmp_reg_reg_word_native(inst,reg1,reg2)     \
+                       md_ucmp_reg_reg_word_32((inst), (reg1), (reg2))
  #endif
  

Index: md_x86.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_x86.h    14 May 2003 06:17:12 -0000      1.1
--- md_x86.h    10 Jul 2003 07:28:17 -0000      1.2
***************
*** 132,136 ****
   * inline using a simple opcode.
   */
! #define       MD_HAS_INT_DIVISION                     0
  
  /*
--- 132,136 ----
   * inline using a simple opcode.
   */
! #define       MD_HAS_INT_DIVISION                     1
  
  /*
***************
*** 232,262 ****
   * Store a byte value to an offset from a pointer register.
   */
! static md_inst_ptr _x86_mov_membase_reg_byte
!                       (md_inst_ptr inst, int basereg, int offset, int srcreg)
! {
!       if(srcreg == X86_EAX || srcreg == X86_EBX ||
!          srcreg == X86_ECX || srcreg == X86_EDX)
!       {
!               x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
!       }
!       else if(basereg != X86_EAX)
!       {
!               x86_push_reg(inst, X86_EAX);
!               x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
!               x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
!               x86_pop_reg(inst, X86_EAX);
!       }
!       else
!       {
!               x86_push_reg(inst, X86_EDX);
!               x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
!               x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
!               x86_pop_reg(inst, X86_EDX);
!       }
!       return inst;
! }
  #define       md_store_membase_byte(inst,reg,basereg,offset)  \
                        do { \
!                               (inst) = _x86_mov_membase_reg_byte      \
                                        ((inst), (basereg), (int)(offset), 
(reg)); \
                        } while (0)
--- 232,240 ----
   * Store a byte value to an offset from a pointer register.
   */
! md_inst_ptr _md_x86_mov_membase_reg_byte
!                       (md_inst_ptr inst, int basereg, int offset, int srcreg);
  #define       md_store_membase_byte(inst,reg,basereg,offset)  \
                        do { \
!                               (inst) = _md_x86_mov_membase_reg_byte   \
                                        ((inst), (basereg), (int)(offset), 
(reg)); \
                        } while (0)
***************
*** 308,312 ****
   * Perform arithmetic and logical operations on 32-bit word registers.
   *
!  * Note: x86 divisions and shifts are handled elsewhere, because they are 
hard.
   */
  #define       md_add_reg_reg_word_32(inst,reg1,reg2)  \
--- 286,290 ----
   * Perform arithmetic and logical operations on 32-bit word registers.
   *
!  * Division is tricky, so it is handled elsewhere for x86.
   */
  #define       md_add_reg_reg_word_32(inst,reg1,reg2)  \
***************
*** 316,319 ****
--- 294,299 ----
  #define       md_mul_reg_reg_word_32(inst,reg1,reg2)  \
                        x86_imul_reg_reg((inst), (reg1), (reg2))
+ extern md_inst_ptr _md_x86_divide(md_inst_ptr inst, int reg1, int reg2,
+                                                                 int isSigned, 
int wantRemainder);
  #define       md_div_reg_reg_word_32(inst,reg1,reg2)  \
                        do { ; } while (0)
***************
*** 334,343 ****
  #define       md_not_reg_word_32(inst,reg)    \
                        x86_not_reg((inst), (reg))
  #define       md_shl_reg_reg_word_32(inst,reg1,reg2)  \
!                       do { ; } while (0)
  #define       md_shr_reg_reg_word_32(inst,reg1,reg2)  \
!                       do { ; } while (0)
  #define       md_ushr_reg_reg_word_32(inst,reg1,reg2) \
!                       do { ; } while (0)
  
  /*
--- 314,327 ----
  #define       md_not_reg_word_32(inst,reg)    \
                        x86_not_reg((inst), (reg))
+ extern md_inst_ptr _md_x86_shift(md_inst_ptr inst, int opc, int reg1, int 
reg2);
  #define       md_shl_reg_reg_word_32(inst,reg1,reg2)  \
!                       do { (inst) = _md_x86_shift \
!                                       ((inst), X86_SHL, (reg1), (reg2)); } 
while (0)
  #define       md_shr_reg_reg_word_32(inst,reg1,reg2)  \
!                       do { (inst) = _md_x86_shift \
!                                       ((inst), X86_SAR, (reg1), (reg2)); } 
while (0)
  #define       md_ushr_reg_reg_word_32(inst,reg1,reg2) \
!                       do { (inst) = _md_x86_shift \
!                                       ((inst), X86_SHR, (reg1), (reg2)); } 
while (0)
  
  /*
***************
*** 355,360 ****
  #define       md_div_reg_reg_float(inst,reg1,reg2)    \
                        x86_fp_op_reg((inst), X86_FDIV, 1, 1)
! #define       md_rem_reg_reg_float(inst,reg1,reg2)    \
!                       do { ; } while (0)
  #define       md_neg_reg_float(inst,reg)      \
                        x86_fchs((inst))
--- 339,347 ----
  #define       md_div_reg_reg_float(inst,reg1,reg2)    \
                        x86_fp_op_reg((inst), X86_FDIV, 1, 1)
! extern md_inst_ptr _md_x86_rem_float
!                       (md_inst_ptr inst, int reg1, int reg2, int used);
! #define       md_rem_reg_reg_float(inst,reg1,reg2,used)       \
!                       do { (inst) = _md_x86_rem_float \
!                                       ((inst), (reg1), (reg2), (used)); } 
while (0)
  #define       md_neg_reg_float(inst,reg)      \
                        x86_fchs((inst))
***************
*** 447,450 ****
--- 434,466 ----
  #define       md_mov_reg_reg(inst,dreg,sreg)  \
                        x86_mov_reg_reg((inst), (dreg), (sreg), 4)
+ 
+ /*
+  * Set a register to a 0 or 1 value based on a condition.
+  */
+ extern md_inst_ptr _md_x86_setcc(md_inst_ptr inst, int reg, int cond);
+ #define       md_seteq_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_EQ); 
} while (0)
+ #define       md_setne_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_NE); 
} while (0)
+ #define       md_setlt_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_LT); 
} while (0)
+ #define       md_setle_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_LE); 
} while (0)
+ #define       md_setgt_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_GT); 
} while (0)
+ #define       md_setge_reg(inst,reg)  \
+                       do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_GE); 
} while (0)
+ 
+ /*
+  * Set a register to -1, 0, or 1 based on comparing two values.
+  */
+ extern md_inst_ptr _md_x86_compare
+                               (md_inst_ptr inst, int reg1, int reg2, int 
isSigned);
+ #define       md_cmp_reg_reg_word_32(inst,reg1,reg2)  \
+                       do { (inst) = _md_x86_compare \
+                                       ((inst), (reg1), (reg2), 1); } while (0)
+ #define       md_ucmp_reg_reg_word_32(inst,reg1,reg2) \
+                       do { (inst) = _md_x86_compare \
+                                       ((inst), (reg1), (reg2), 0); } while (0)
  
  #ifdef        __cplusplus

Index: unroll.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/unroll.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** unroll.c    14 May 2003 06:17:12 -0000      1.1
--- unroll.c    10 Jul 2003 07:28:17 -0000      1.2
***************
*** 1278,1282 ****
   */
  #define       IL_UNROLL_GLOBAL
! //#include "unroll_arith.c"
  //#include "unroll_branch.c"
  //#include "unroll_const.c"
--- 1278,1282 ----
   */
  #define       IL_UNROLL_GLOBAL
! #include "unroll_arith.c"
  //#include "unroll_branch.c"
  //#include "unroll_const.c"
***************
*** 1360,1364 ****
                {
                        #define IL_UNROLL_CASES
!                       //#include "unroll_arith.c"
                        //#include "unroll_branch.c"
                        //#include "unroll_const.c"
--- 1360,1364 ----
                {
                        #define IL_UNROLL_CASES
!                       #include "unroll_arith.c"
                        //#include "unroll_branch.c"
                        //#include "unroll_const.c"





reply via email to

[Prev in Thread] Current Thread [Next in Thread]