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 unroll_const.c, NONE, 1.1 unroll_


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

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

Modified Files:
        md_arm.h md_x86.c md_x86.h unroll.c 
Added Files:
        unroll_const.c unroll_ptr.c 
Log Message:


Implement generic unrolling for constant and pointer operations.


--- NEW FILE ---
/*
 * unroll_const.c - Constant 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_CASES

case COP_LDNULL:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_zero_native(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_0:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_zero_32(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_M1:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_1:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_2:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 2);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_3:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 3);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_4:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 4);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_5:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 5);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_6:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 6);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_7:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 7);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_8:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, 8);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_LDC_I4_S:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, (int)CVM_ARG_SBYTE);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_LDC_I4:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_32BIT);
        md_load_const_32(unroll.out, reg, (ILInt32)CVM_ARG_WORD);
        MODIFY_UNROLL_PC(CVM_LEN_WORD);
}
break;

#ifdef MD_HAS_FP

case COP_LDC_R4:
{
        UNROLL_START();
        reg = GetFPRegister(&unroll);
        md_load_const_float_32(unroll.out, reg, pc + sizeof(void *));
        MODIFY_UNROLL_PC(CVM_LEN_FLOAT);
}
break;

case COP_LDC_R8:
{
        UNROLL_START();
        reg = GetFPRegister(&unroll);
        md_load_const_float_64(unroll.out, reg, pc + sizeof(void *));
        MODIFY_UNROLL_PC(CVM_LEN_DOUBLE);
}
break;

#endif /* MD_HAS_FP */

case COP_LDTOKEN:
{
        UNROLL_START();
        reg = GetWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_const_native(unroll.out, reg, (ILNativeInt)(CVM_ARG_PTR(void 
*)));
        MODIFY_UNROLL_PC(CVM_LEN_PTR);
}
break;

#endif /* IL_UNROLL_CASES */

--- NEW FILE ---
/*
 * unroll_ptr.c - Pointer 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

/*
 * Check the contents of a register for NULL and re-execute
 * the current instruction in the interpreter if it is.
 */
static void CheckForNull(MDUnroll *unroll, int reg, unsigned char *pc,
                                                 unsigned char *label, int 
popReg)
{
        md_inst_ptr patch;

        /* Check the register's contents against NULL */
        md_reg_is_null(unroll->out, reg);
        patch = unroll->out;
        md_branch_ne(unroll->out);

        /* Re-execute the current instruction in the interpreter */
        if(popReg)
        {
                --(unroll->pseudoStackSize);
                ReExecute(unroll, pc, label);
                ++(unroll->pseudoStackSize);
        }
        else
        {
                ReExecute(unroll, pc, label);
        }

        /* Continue with real execution here */
        md_patch(patch, unroll->out);
}

/*
 * Check an array access operation for exception conditions.
 */
static void CheckArrayAccess(MDUnroll *unroll, int reg, int reg2,
                                                         unsigned char *pc, 
unsigned char *label)
{
        md_inst_ptr patch1;
        md_inst_ptr patch2;

        /* Check the array reference against NULL */
        md_reg_is_null(unroll->out, reg);
        patch1 = unroll->out;
        md_branch_eq(unroll->out);

        /* Check the array bounds */
        md_bounds_check(unroll->out, reg, reg2);
        patch2 = unroll->out;
        md_branch_lt_un(unroll->out);

        /* Re-execute the current instruction in the interpreter */
        md_patch(patch1, unroll->out);
        ReExecute(unroll, pc, label);

        /* Continue with real execution here */
        md_patch(patch2, unroll->out);
}

/*
 * Bounds checking for 2D arrays is a bit complicated, so we have
 * to do it specially for each CPU type, unfortunately.
 */

#ifdef CVM_X86

#define MD_HAS_2D_ARRAYS        1

/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
                                                           unsigned char *pc, 
unsigned char *label)
{
        unsigned char *patch1;
        unsigned char *patch2;
        unsigned char *patch3;

        /* Check the array reference against NULL */
        x86_alu_reg_reg(unroll->out, X86_OR, reg, reg);
        patch1 = unroll->out;
        x86_branch8(unroll->out, X86_CC_EQ, 0, 0);

        /* Check the array bounds */
        x86_alu_reg_membase(unroll->out, X86_SUB, reg2, reg, 12);
        x86_alu_reg_membase(unroll->out, X86_CMP, reg2, reg, 16);
        patch2 = unroll->out;
        x86_branch32(unroll->out, X86_CC_LT, 0, 0);
        x86_alu_reg_membase(unroll->out, X86_ADD, reg2, reg, 12);
        patch3 = unroll->out;
        x86_jump8(unroll->out, 0);
        x86_patch(patch2, unroll->out);
        x86_alu_reg_membase(unroll->out, X86_SUB, reg3, reg, 24);
        x86_alu_reg_membase(unroll->out, X86_CMP, reg3, reg, 28);
        patch2 = unroll->out;
        x86_branch32(unroll->out, X86_CC_LT, 0, 0);
        x86_alu_reg_membase(unroll->out, X86_ADD, reg2, reg, 12);
        x86_alu_reg_membase(unroll->out, X86_ADD, reg3, reg, 28);

        /* Re-execute the current instruction in the interpreter */
        x86_patch(patch1, unroll->out);
        x86_patch(patch3, unroll->out);
        ReExecute(unroll, pc, label);

        /* Compute the address of the array element */
        x86_patch(patch2, unroll->out);
        x86_imul_reg_membase(unroll->out, reg2, reg, 20);
        x86_imul_reg_membase(unroll->out, reg3, reg, 32);
        x86_alu_reg_reg(unroll->out, X86_ADD, reg2, reg3);
        x86_imul_reg_membase(unroll->out, reg2, reg, 4);
        x86_mov_reg_membase(unroll->out, reg, reg, 8, 4);
        x86_alu_reg_reg(unroll->out, X86_ADD, reg, reg2);
}

#endif /* CVM_X86 */

#ifdef CVM_ARM

#define MD_HAS_2D_ARRAYS        1

/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
                                                           unsigned char *pc, 
unsigned char *label)
{
        md_inst_ptr patch1;
        md_inst_ptr patch2;
        md_inst_ptr patch3;

        /* Check the array reference against NULL */
        arm_test_reg_imm8(unroll->out, ARM_CMP, reg, 0);
        patch1 = unroll->out;
        arm_branch_imm(unroll->out, ARM_CC_EQ, 0);

        /* Check the array bounds.  We assume that we can use the link
           register as a work register because "lr" would have been
           saved on entry to "_ILCVMInterpreter" */
        arm_load_membase(unroll->out, ARM_WORK, reg, 12);
        arm_alu_reg_reg(unroll->out, ARM_SUB, reg2, reg2, ARM_WORK);
        arm_load_membase(unroll->out, ARM_LINK, reg, 16);
        arm_test_reg_reg(unroll->out, ARM_CMP, reg2, ARM_LINK);
        patch2 = unroll->out;
        arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
        arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);
        patch3 = unroll->out;
        arm_jump_imm(unroll->out, 0);
        arm_patch(patch2, unroll->out);
        arm_load_membase(unroll->out, ARM_WORK, reg, 24);
        arm_alu_reg_reg(unroll->out, ARM_SUB, reg3, reg3, ARM_WORK);
        arm_load_membase(unroll->out, ARM_LINK, reg, 28);
        arm_test_reg_reg(unroll->out, ARM_CMP, reg3, ARM_LINK);
        patch2 = unroll->out;
        arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
        arm_alu_reg_reg(unroll->out, ARM_ADD, reg3, reg3, ARM_WORK);
        arm_load_membase(unroll->out, ARM_WORK, reg, 12);
        arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);

        /* Re-execute the current instruction in the interpreter */
        arm_patch(patch1, unroll->out);
        arm_patch(patch3, unroll->out);
        ReExecute(unroll, pc, label);

        /* Compute the address of the array element */
        arm_patch(patch2, unroll->out);
        arm_load_membase(unroll->out, ARM_WORK, reg, 20);
        arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
        arm_load_membase(unroll->out, ARM_WORK, reg, 32);
        arm_mul_reg_reg(unroll->out, reg3, reg3, ARM_WORK);
        arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, reg3);
        arm_load_membase(unroll->out, ARM_WORK, reg, 4);
        arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
        arm_load_membase(unroll->out, reg, reg, 8);
        arm_alu_reg_reg(unroll->out, ARM_ADD, reg, reg, reg2);
}

#endif /* CVM_ARM */

#elif defined(IL_UNROLL_CASES)

case COP_BREAD:
{
        /* Read a signed byte value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_sbyte(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_UBREAD:
{
        /* Read an unsigned byte value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_byte(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_SREAD:
{
        /* Read a signed short value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_short(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_USREAD:
{
        /* Read an unsigned short value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_ushort(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IREAD:
{
        /* Read a 32-bit word value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_word_32(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PREAD:
{
        /* Read a native word value from a pointer */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_word_native(unroll.out, reg, reg, 0);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef MD_HAS_FP

case COP_FREAD:
{
        /* Read a float32 value from a pointer */
        UNROLL_START();
        CheckFPFull(&unroll);
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        reg2 = GetFPRegister(&unroll);
        md_load_membase_float_32(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        PushRegister(&unroll, reg2, 0);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_DREAD:
{
        /* Read a float64 value from a pointer */
        UNROLL_START();
        CheckFPFull(&unroll);
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        reg2 = GetFPRegister(&unroll);
        md_load_membase_float_64(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        PushRegister(&unroll, reg2, 0);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* MD_HAS_FP */

case COP_BWRITE:
{
        /* Write a byte value to a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        md_store_membase_byte(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_SWRITE:
{
        /* Write a short value to a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        md_store_membase_short(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IWRITE:
{
        /* Write a word value to a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        md_store_membase_word_32(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PWRITE:
{
        /* Write a native word value to a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_store_membase_word_native(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef MD_HAS_FP

case COP_FWRITE:
{
        /* Write a float32 value to a pointer */
        UNROLL_START();
        GetWordAndFPRegisters(&unroll, &reg, &reg2);
        md_store_membase_float_32(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_DWRITE:
{
        /* Write a float64 value to a pointer */
        UNROLL_START();
        GetWordAndFPRegisters(&unroll, &reg, &reg2);
        md_store_membase_float_64(unroll.out, reg2, reg, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* MD_HAS_FP */

case COP_BWRITE_R:
{
        /* Write a byte value to a pointer with reversed arguments */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_NATIVE);
        md_store_membase_byte(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_SWRITE_R:
{
        /* Write a short value to a pointer with reversed arguments */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_NATIVE);
        md_store_membase_short(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IWRITE_R:
{
        /* Write a word value to a pointer with reversed arguments */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_NATIVE);
        md_store_membase_word_32(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PWRITE_R:
{
        /* Write a native word value to a pointer with reversed arguments */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_store_membase_word_native(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef MD_HAS_FP

case COP_FWRITE_R:
{
        /* Write a float32 value to a pointer with reversed arguments */
        UNROLL_START();
        GetFPAndWordRegisters(&unroll, &reg, &reg2);
        md_store_membase_float_32(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_DWRITE_R:
{
        /* Write a float64 value to a pointer with reversed arguments */
        UNROLL_START();
        GetFPAndWordRegisters(&unroll, &reg, &reg2);
        md_store_membase_float_64(unroll.out, reg, reg2, 0);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* MD_HAS_FP */

case COP_PADD_OFFSET:
{
        /* Add an offset value to a pointer */
        unsigned val = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_add_reg_imm(unroll.out, reg, val);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_PADD_I4:
{
        /* Add an integer value to a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        md_reg_to_word_native(unroll.out, reg2);
        md_add_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PADD_I4_R:
{
        /* Add an integer value to a pointer with reversed arguments */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_NATIVE);
        md_reg_to_word_native(unroll.out, reg);
        md_add_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PSUB:
{
        /* Subtract pointers */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_sub_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PSUB_I4:
{
        /* Subtract an integer from a pointer */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        md_reg_to_word_native(unroll.out, reg2);
        md_sub_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#define MD_ARRAY_HEADER         (sizeof(System_Array))

case COP_BREAD_ELEM:
{
        /* Read a byte from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_sbyte(unroll.out, reg, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_UBREAD_ELEM:
{
        /* Read an unsigned byte from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_byte(unroll.out, reg, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_SREAD_ELEM:
{
        /* Read a short from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_short(unroll.out, reg, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_USREAD_ELEM:
{
        /* Read an unsigned short from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_ushort(unroll.out, reg, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IREAD_ELEM:
{
        /* Read a word from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_word_32(unroll.out, reg, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PREAD_ELEM:
{
        /* Read a native word from an array */
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_load_memindex_word_native(unroll.out, reg, reg, reg2, 
MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_BWRITE_ELEM:
{
        /* Write a byte to an array */
        UNROLL_START();
        GetTopThreeWordRegisters(&unroll, &reg, &reg2, &reg3,
                                                         MD_REG1_NATIVE | 
MD_REG2_32BIT | MD_REG3_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_store_memindex_byte(unroll.out, reg3, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_SWRITE_ELEM:
{
        /* Write a short to an array */
        UNROLL_START();
        GetTopThreeWordRegisters(&unroll, &reg, &reg2, &reg3,
                                                         MD_REG1_NATIVE | 
MD_REG2_32BIT | MD_REG3_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_store_memindex_short(unroll.out, reg3, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_IWRITE_ELEM:
{
        /* Write a word to an array */
        UNROLL_START();
        GetTopThreeWordRegisters(&unroll, &reg, &reg2, &reg3,
                                                         MD_REG1_NATIVE | 
MD_REG2_32BIT | MD_REG3_32BIT);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_store_memindex_word_32(unroll.out, reg3, reg, reg2, MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_PWRITE_ELEM:
{
        /* Write a word to an array */
        UNROLL_START();
        GetTopThreeWordRegisters(&unroll, &reg, &reg2, &reg3,
                                                         MD_REG1_NATIVE | 
MD_REG2_32BIT | MD_REG3_NATIVE);
        CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
        md_store_memindex_word_native(unroll.out, reg3, reg, reg2, 
MD_ARRAY_HEADER);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_ARRAY_LEN:
{
        /* Get the length of an array */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_word_32(unroll.out, reg, reg, 0);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_BREAD_FIELD:
{
        /* Read a byte field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_sbyte(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_UBREAD_FIELD:
{
        /* Read an unsigned byte field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_byte(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_SREAD_FIELD:
{
        /* Read a short field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_short(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_USREAD_FIELD:
{
        /* Read an unsigned byte field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_ushort(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_IREAD_FIELD:
{
        /* Read a word field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_word_32(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_PREAD_FIELD:
{
        /* Read a word field from an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_load_membase_word_native(unroll.out, reg, reg, (int)temp);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_BWRITE_FIELD:
{
        /* Write a byte field to an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_store_membase_byte(unroll.out, reg2, reg, (int)temp);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_SWRITE_FIELD:
{
        /* Write a short field to an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_store_membase_short(unroll.out, reg2, reg, (int)temp);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_IWRITE_FIELD:
{
        /* Write a word field to an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_store_membase_word_32(unroll.out, reg2, reg, (int)temp);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_PWRITE_FIELD:
{
        /* Write a word field to an object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_32BIT);
        CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
        md_store_membase_word_native(unroll.out, reg2, reg, (int)temp);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_IREAD_THIS:
{
        /* Read a word field from the "this" object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();

        /* Load "this" into a new register */
        reg = GetWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_word_native(unroll.out, reg, MD_REG_FRAME, 0);

        /* Check "this" for NULL if we haven't done so already.
           If "thisValidated" is -1, then it indicates that the
           "this" variable has been addressed using "waddr" and
           so we must always validate it just in case someone
           writes to that address further down the code */
        if(unroll.thisValidated <= 0)
        {
                CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 1);
                if(!(unroll.thisValidated))
                {
                        unroll.thisValidated = 1;
                }
        }

        /* Read the contents of the field */
        md_load_membase_word_32(unroll.out, reg, reg, (int)temp);
        ChangeRegisterType(&unroll, MD_REG1_32BIT);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

case COP_PREAD_THIS:
{
        /* Read a native word field from the "this" object */
        unsigned temp = (unsigned)CVM_ARG_BYTE;
        UNROLL_START();

        /* Load "this" into a new register */
        reg = GetWordRegister(&unroll, MD_REG1_NATIVE);
        md_load_membase_word_native(unroll.out, reg, MD_REG_FRAME, 0);

        /* Check "this" for NULL if we haven't done so already.
           If "thisValidated" is -1, then it indicates that the
           "this" variable has been addressed using "waddr" and
           so we must always validate it just in case someone
           writes to that address further down the code */
        if(unroll.thisValidated <= 0)
        {
                CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 1);
                if(!(unroll.thisValidated))
                {
                        unroll.thisValidated = 1;
                }
        }

        /* Read the contents of the field */
        md_load_membase_word_native(unroll.out, reg, reg, (int)temp);
        MODIFY_UNROLL_PC(CVM_LEN_BYTE);
}
break;

#ifdef MD_HAS_2D_ARRAYS

case 0x100 + COP_PREFIX_GET2D:
{
        /* Get the array object reference and indices into registers */
        UNROLL_START();
        GetTopThreeWordRegisters(&unroll, &reg, &reg2, &reg3,
                                                         MD_REG1_NATIVE | 
MD_REG2_32BIT |
                                                         MD_REG3_32BIT);

        /* Check the access and compute the element address */
        Check2DArrayAccess(&unroll, reg, reg2, reg3, pc, (unsigned char *)inst);

        /* Pop unnecessary registers: the address is now in "reg" */
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);

        /* Skip to the next instruction */
        MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;

case 0x100 + COP_PREFIX_SET2D:
{
        unsigned temp = (unsigned)CVMP_ARG_WORD;
        int offset;

        /* Flush the register stack onto the real stack so that we know
           where everything is */
        UNROLL_START();
        FlushRegisterStack(&unroll);
        offset = unroll.stackHeight - ((int)((temp + 3) * sizeof(CVMWord)));

        /* Fetch the array object reference and indices */
        reg = regAllocOrder[0];
        reg2 = regAllocOrder[1];
        reg3 = regAllocOrder[2];
        md_load_membase_word_native(unroll.out, reg, MD_REG_STACK, offset);
        md_load_membase_word_32(unroll.out, reg2, MD_REG_STACK,
                                                        offset + 
sizeof(CVMWord));
        md_load_membase_word_32(unroll.out, reg3, MD_REG_STACK,
                                                        offset + 
sizeof(CVMWord) * 2);

        /* Check the access and compute the element address */
        Check2DArrayAccess(&unroll, reg, reg2, reg3, pc, (unsigned char *)inst);

        /* Shift everything down on the stack to squash out the indices */
        md_store_membase_word_native(unroll.out, reg, MD_REG_STACK, offset);
        temp = (temp * sizeof(CVMWord)) / sizeof(ILNativeInt);
        offset += sizeof(CVMWord);
        while(temp > 0)
        {
                md_load_membase_word_native(unroll.out, reg2, MD_REG_STACK,
                                                                        offset 
+ sizeof(CVMWord) * 2);
                md_store_membase_word_native(unroll.out, reg2, MD_REG_STACK, 
offset);
                offset += sizeof(ILNativeInt);
                --temp;
        }

        /* Adjust the top of stack pointer */
        unroll.stackHeight -= sizeof(CVMWord) * 2;

        /* Skip to the next instruction */
        MODIFY_UNROLL_PC(CVMP_LEN_WORD);
}
break;

#endif /* MD_HAS_2D_ARRAYS */

#endif /* IL_UNROLL_CASES */

Index: md_arm.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_arm.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** md_arm.h    10 Jul 2003 07:28:17 -0000      1.2
--- md_arm.h    11 Jul 2003 00:58:25 -0000      1.3
***************
*** 164,167 ****
--- 164,194 ----
  
  /*
+  * Load a 32-bit floating-point constant into a register.  The constant
+  * is at a particular memory location.  If the system does not use
+  * floating-point registers, then load onto the top of the stack.
+  */
+ #define       md_load_const_float_32(inst,reg,mem)    do { ; } while (0)
+ 
+ /*
+  * Load a 64-bit floating-point constant into a register.  The constant
+  * is at a particular memory location.  If the system does not use
+  * floating-point registers, then load onto the top of the stack.
+  */
+ #define       md_load_const_float_64(inst,reg,mem)    do { ; } while (0)
+ 
+ /*
+  * Load the 32-bit constant zero into a register.  This will zero-extend
+  * if the native word size is larger.
+  */
+ #define       md_load_zero_32(inst,reg)       \
+                       arm_mov_reg_imm((inst), (reg), 0)
+ 
+ /*
+  * Load the native constant zero into a register.
+  */
+ #define       md_load_zero_native(inst,reg)   \
+                       arm_mov_reg_imm((inst), (reg), 0)
+ 
+ /*
   * Load a 32-bit word register from an offset from a pointer register.
   * This will sign-extend if the native word size is larger.
***************
*** 332,335 ****
--- 359,364 ----
  #define       md_reg_to_word_native(inst,reg) \
                        do { ; } while (0)
+ #define       md_reg_to_word_native_un(inst,reg)      \
+                       do { ; } while (0)
  
  /*
***************
*** 353,357 ****
  #define       md_jump_to_cvm(inst,pc,label)   \
                        do { \
!                               /* TODO */ \
                        } while (0)
  
--- 382,414 ----
  #define       md_jump_to_cvm(inst,pc,label)   \
                        do { \
!                               int offset; \
!                               if(!(label)) \
!                               { \
!                                       /* Jump to the contents of the 
specified PC */ \
!                                       arm_load_membase((inst), MD_REG_PC, 
ARM_PC, 0); \
!                                       arm_load_membase((inst), ARM_PC, 
MD_REG_PC, 0); \
!                                       *((inst)++) = (unsigned int)(pc); \
!                               } \
!                               else \
!                               { \
!                                       /* Load "pc" back into the CVM 
interpreter's frame */ \
!                                       /* and then jump directly to 
instruction handler at */ \
!                                       /* "label".  This avoids the need for 
an indirect */ \
!                                       /* jump instruction */ \
!                                       arm_load_membase(unroll->out, 
MD_REG_PC, ARM_PC, 0); \
!                                       offset = (int)(((unsigned char 
*)(label)) - \
!                                                         (((unsigned char 
*)(inst)) + 8)); \
!                                       if(offset >= -0x04000000 && offset < 
0x04000000) \
!                                       { \
!                                               arm_jump_imm((inst), offset); \
!                                               *((inst)++) = (unsigned 
int)(pc); \
!                                       } \
!                                       else \
!                                       { \
!                                               arm_load_membase(unroll->out, 
ARM_PC, ARM_PC, 0); \
!                                               *((inst)++) = (unsigned 
int)(pc); \
!                                               *((inst)++) = (unsigned 
int)(label); \
!                                       } \
!                               } \
                        } while (0)
  
***************
*** 431,434 ****
--- 488,614 ----
                                                                 ARM_CC_LT_UN); 
\
                        } while (0)
+ 
+ /*
+  * Test the contents of a register against NULL and set the
+  * condition codes based on the result.
+  */
+ #define       md_reg_is_null(inst,reg)        \
+                       arm_test_reg_imm8((inst), ARM_CMP, (reg), 0)
+ 
+ /*
+  * Output a branch to a location based on a condition.  The actual
+  * jump offset will be filled in by a later "md_patch" call.
+  */
+ #define       md_branch_eq(inst)      \
+                       arm_branch_imm((inst), ARM_CC_EQ, 0)
+ #define       md_branch_ne(inst)      \
+                       arm_branch_imm((inst), ARM_CC_NE, 0)
+ #define       md_branch_lt(inst)      \
+                       arm_branch_imm((inst), ARM_CC_LT, 0)
+ #define       md_branch_le(inst)      \
+                       arm_branch_imm((inst), ARM_CC_LE, 0)
+ #define       md_branch_gt(inst)      \
+                       arm_branch_imm((inst), ARM_CC_GT, 0)
+ #define       md_branch_ge(inst)      \
+                       arm_branch_imm((inst), ARM_CC_GE, 0)
+ #define       md_branch_lt_un(inst)   \
+                       arm_branch_imm((inst), ARM_CC_LT_UN, 0)
+ #define       md_branch_le_un(inst)   \
+                       arm_branch_imm((inst), ARM_CC_LE_UN, 0)
+ #define       md_branch_gt_un(inst)   \
+                       arm_branch_imm((inst), ARM_CC_GT_UN, 0)
+ #define       md_branch_ge_un(inst)   \
+                       arm_branch_imm((inst), ARM_CC_GE_UN, 0)
+ 
+ /*
+  * Back-patch a branch instruction at "patch" to branch to "inst".
+  */
+ #define       md_patch(patch,inst)    \
+                       arm_patch((patch), (inst))
+ 
+ /*
+  * Check an array bounds value.  "reg1" points to the array,
+  * and "reg2" is the array index to check.  This will advance
+  * the pointer in "reg1" past the array bounds value.
+  */
+ #define       md_bounds_check(inst,reg1,reg2) \
+                       do { \
+                               arm_load_advance((inst), ARM_WORK, (reg1)); \
+                               arm_test_reg_reg((inst), ARM_CMP, (reg2), 
ARM_WORK); \
+                       } while (0)
+ 
+ /*
+  * Load a 32-bit word value from an indexed array.  "disp" is the offset
+  * to use to skip over the array bounds value.  Some platforms may ignore
+  * "disp" if they advance the base pointer in "md_bounds_check".
+  */
+ #define       md_load_memindex_word_32(inst,reg,basereg,indexreg,disp)        
\
+                       arm_load_memindex((inst), (reg), (basereg), (indexreg))
+ 
+ /*
+  * Load a native word value from an indexed array.
+  */
+ #define       md_load_memindex_word_native(inst,reg,basereg,indexreg,disp)    
\
+                       arm_load_memindex((inst), (reg), (basereg), (indexreg))
+ 
+ /*
+  * Load a byte value from an indexed array.
+  */
+ #define       md_load_memindex_byte(inst,reg,basereg,indexreg,disp)   \
+                       arm_load_memindex_byte((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Load a signed byte value from an indexed array.
+  */
+ #define       md_load_memindex_sbyte(inst,reg,basereg,indexreg,disp)  \
+                       arm_load_memindex_sbyte((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Load a short value from an indexed array.
+  */
+ #define       md_load_memindex_short(inst,reg,basereg,indexreg,disp)  \
+                       arm_load_memindex_short((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Load an unsigned short value from an indexed array.
+  */
+ #define       md_load_memindex_ushort(inst,reg,basereg,indexreg,disp) \
+                       arm_load_memindex_ushort((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Store a 32-bit word value into an indexed array.
+  */
+ #define       md_store_memindex_word_32(inst,reg,basereg,indexreg,disp)       
\
+                       arm_store_memindex((inst), (reg), (basereg), (indexreg))
+ 
+ /*
+  * Store a native word value into an indexed array.
+  */
+ #define       md_store_memindex_word_native(inst,reg,basereg,indexreg,disp)   
\
+                       arm_store_memindex((inst), (reg), (basereg), (indexreg))
+ 
+ /*
+  * Store a byte value into an indexed array.
+  */
+ #define       md_store_memindex_byte(inst,reg,basereg,indexreg,disp)  \
+                       arm_store_memindex_byte((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Store a signed byte value into an indexed array.
+  */
+ #define       md_store_memindex_sbyte(inst,reg,basereg,indexreg,disp) \
+                       arm_store_memindex_sbyte((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Store a short value into an indexed array.
+  */
+ #define       md_store_memindex_short(inst,reg,basereg,indexreg,disp) \
+                       arm_store_memindex_short((inst), (reg), (basereg), 
(indexreg))
+ 
+ /*
+  * Store an unsigned short value into an indexed array.
+  */
+ #define       md_store_memindex_ushort(inst,reg,basereg,indexreg,disp)        
\
+                       arm_store_memindex_ushort((inst), (reg), (basereg), 
(indexreg))
  
  #ifdef        __cplusplus

Index: md_x86.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_x86.c    10 Jul 2003 07:28:17 -0000      1.1
--- md_x86.c    11 Jul 2003 00:58:25 -0000      1.2
***************
*** 75,78 ****
--- 75,112 ----
  }
  
+ md_inst_ptr _md_x86_mov_memindex_reg_byte(md_inst_ptr inst, int basereg,
+                                                                               
  unsigned offset, int indexreg,
+                                                                               
  int srcreg)
+ {
+       if(srcreg == X86_EAX || srcreg == X86_EBX ||
+          srcreg == X86_ECX || srcreg == X86_EDX)
+       {
+               x86_mov_memindex_reg(inst, basereg, offset, indexreg,
+                                                        0, srcreg, 1);
+       }
+       else
+       {
+               int tempreg;
+               if(basereg != X86_EAX && indexreg != X86_EAX)
+               {
+                       tempreg = X86_EAX;
+               }
+               else if(basereg != X86_ECX && indexreg != X86_ECX)
+               {
+                       tempreg = X86_ECX;
+               }
+               else
+               {
+                       tempreg = X86_EDX;
+               }
+               x86_push_reg(inst, tempreg);
+               x86_mov_reg_reg(inst, tempreg, srcreg, 4);
+               x86_mov_memindex_reg(inst, basereg, offset, indexreg,
+                                                        0, tempreg, 1);
+               x86_pop_reg(inst, tempreg);
+       }
+       return inst;
+ }
+ 
  md_inst_ptr _md_x86_rem_float
                (md_inst_ptr inst, int reg1, int reg2, int used)

Index: md_x86.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** md_x86.h    10 Jul 2003 07:28:17 -0000      1.2
--- md_x86.h    11 Jul 2003 00:58:25 -0000      1.3
***************
*** 168,171 ****
--- 168,200 ----
  
  /*
+  * Load a 32-bit floating-point constant into a register.  The constant
+  * is at a particular memory location.  If the system does not use
+  * floating-point registers, then load onto the top of the stack.
+  */
+ #define       md_load_const_float_32(inst,reg,mem)    \
+                       x86_fld((inst), (int)(mem), 0)
+ 
+ /*
+  * Load a 64-bit floating-point constant into a register.  The constant
+  * is at a particular memory location.  If the system does not use
+  * floating-point registers, then load onto the top of the stack.
+  */
+ #define       md_load_const_float_64(inst,reg,mem)    \
+                       x86_fld((inst), (int)(mem), 1)
+ 
+ /*
+  * Load the 32-bit constant zero into a register.  This will zero-extend
+  * if the native word size is larger.
+  */
+ #define       md_load_zero_32(inst,reg)       \
+                       x86_clear_reg((inst), (reg))
+ 
+ /*
+  * Load the native constant zero into a register.
+  */
+ #define       md_load_zero_native(inst,reg)   \
+                       x86_clear_reg((inst), (reg))
+ 
+ /*
   * Load a 32-bit word register from an offset from a pointer register.
   * This will sign-extend if the native word size is larger.
***************
*** 362,365 ****
--- 391,396 ----
  #define       md_reg_to_word_native(inst,reg) \
                        do { ; } while (0)
+ #define       md_reg_to_word_native_un(inst,reg)      \
+                       do { ; } while (0)
  
  /*
***************
*** 463,466 ****
--- 494,655 ----
                        do { (inst) = _md_x86_compare \
                                        ((inst), (reg1), (reg2), 0); } while (0)
+ 
+ /*
+  * Test the contents of a register against NULL and set the
+  * condition codes based on the result.
+  */
+ #define       md_reg_is_null(inst,reg)        \
+                       x86_alu_reg_reg((inst), X86_OR, (reg), (reg))
+ 
+ /*
+  * Output a branch to a location based on a condition.  The actual
+  * jump offset will be filled in by a later "md_patch" call.
+  */
+ #define       md_branch_eq(inst)      \
+                       x86_branch32((inst), X86_CC_EQ, 0, 0)
+ #define       md_branch_ne(inst)      \
+                       x86_branch32((inst), X86_CC_NE, 0, 0)
+ #define       md_branch_lt(inst)      \
+                       x86_branch32((inst), X86_CC_LT, 0, 1)
+ #define       md_branch_le(inst)      \
+                       x86_branch32((inst), X86_CC_LE, 0, 1)
+ #define       md_branch_gt(inst)      \
+                       x86_branch32((inst), X86_CC_GT, 0, 1)
+ #define       md_branch_ge(inst)      \
+                       x86_branch32((inst), X86_CC_GE, 0, 1)
+ #define       md_branch_lt_un(inst)   \
+                       x86_branch32((inst), X86_CC_LT, 0, 0)
+ #define       md_branch_le_un(inst)   \
+                       x86_branch32((inst), X86_CC_LE, 0, 0)
+ #define       md_branch_gt_un(inst)   \
+                       x86_branch32((inst), X86_CC_GT, 0, 0)
+ #define       md_branch_ge_un(inst)   \
+                       x86_branch32((inst), X86_CC_GE, 0, 0)
+ 
+ /*
+  * Back-patch a branch instruction at "patch" to branch to "inst".
+  */
+ #define       md_patch(patch,inst)    \
+                       x86_patch((patch), (inst))
+ 
+ /*
+  * Check an array bounds value.  "reg1" points to the array,
+  * and "reg2" is the array index to check.
+  */
+ #define       md_bounds_check(inst,reg1,reg2) \
+                       x86_alu_reg_membase((inst), X86_CMP, (reg2), (reg1), 0)
+ 
+ /*
+  * Load a 32-bit word value from an indexed array.  "disp" is the offset
+  * to use to skip over the array bounds value.  Some platforms may ignore
+  * "disp" if they advance the base pointer in "md_bounds_check".
+  */
+ #define       md_load_memindex_word_32(inst,reg,basereg,indexreg,disp)        
\
+                       do { \
+                               x86_mov_reg_memindex((inst), (reg), (basereg), \
+                                                                        
(disp), (indexreg), 2, 4); \
+                       } while (0)
+ 
+ /*
+  * Load a native word value from an indexed array.
+  */
+ #define       md_load_memindex_word_native(inst,reg,basereg,indexreg,disp)    
\
+                       do { \
+                               x86_mov_reg_memindex((inst), (reg), (basereg), \
+                                                                        
(disp), (indexreg), 2, 4); \
+                       } while (0)
+ 
+ /*
+  * Load a byte value from an indexed array.
+  */
+ #define       md_load_memindex_byte(inst,reg,basereg,indexreg,disp)   \
+                       do { \
+                               x86_widen_memindex((inst), (reg), (basereg), \
+                                                                  (disp), 
(indexreg), 0, 1, 0); \
+                       } while (0)
+ 
+ /*
+  * Load a signed byte value from an indexed array.
+  */
+ #define       md_load_memindex_sbyte(inst,reg,basereg,indexreg,disp)  \
+                       do { \
+                               x86_widen_memindex((inst), (reg), (basereg), \
+                                                                  (disp), 
(indexreg), 0, 0, 0); \
+                       } while (0)
+ 
+ /*
+  * Load a short value from an indexed array.
+  */
+ #define       md_load_memindex_short(inst,reg,basereg,indexreg,disp)  \
+                       do { \
+                               x86_widen_memindex((inst), (reg), (basereg), \
+                                                                  (disp), 
(indexreg), 1, 1, 1); \
+                       } while (0)
+ 
+ /*
+  * Load an unsigned short value from an indexed array.
+  */
+ #define       md_load_memindex_ushort(inst,reg,basereg,indexreg,disp) \
+                       do { \
+                               x86_widen_memindex((inst), (reg), (basereg), \
+                                                                  (disp), 
(indexreg), 1, 0, 1); \
+                       } while (0)
+ 
+ /*
+  * Store a 32-bit word value into an indexed array.
+  */
+ #define       md_store_memindex_word_32(inst,reg,basereg,indexreg,disp)       
\
+                       do { \
+                               x86_mov_memindex_reg((inst), (basereg), (disp), 
(indexreg), \
+                                                                        2, 
(reg), 4); \
+                       } while (0)
+ 
+ /*
+  * Store a native word value into an indexed array.
+  */
+ #define       md_store_memindex_word_native(inst,reg,basereg,indexreg,disp)   
\
+                       do { \
+                               x86_mov_memindex_reg((inst), (basereg), (disp), 
(indexreg), \
+                                                                        2, 
(reg), 4); \
+                       } while (0)
+ 
+ /*
+  * Store a byte value into an indexed array.
+  */
+ extern md_inst_ptr _md_x86_mov_memindex_reg_byte
+                       (md_inst_ptr inst, int basereg,
+                        unsigned offset, int indexreg, int srcreg);
+ #define       md_store_memindex_byte(inst,reg,basereg,indexreg,disp)  \
+                       do { \
+                               (inst) = _md_x86_mov_memindex_reg_byte \
+                                       ((inst), (basereg), (disp), (indexreg), 
(reg)); \
+                       } while (0)
+ 
+ /*
+  * Store a signed byte value into an indexed array.
+  */
+ #define       md_store_memindex_sbyte(inst,reg,basereg,indexreg,disp) \
+                       do { \
+                               (inst) = _md_x86_mov_memindex_reg_byte \
+                                       ((inst), (basereg), (disp), (indexreg), 
(reg)); \
+                       } while (0)
+ 
+ /*
+  * Store a short value into an indexed array.
+  */
+ #define       md_store_memindex_short(inst,reg,basereg,indexreg,disp) \
+                       do { \
+                               x86_mov_memindex_reg((inst), (basereg), (disp), 
(indexreg), \
+                                                                        1, 
(reg), 2); \
+                       } while (0)
+ 
+ /*
+  * Store an unsigned short value into an indexed array.
+  */
+ #define       md_store_memindex_ushort(inst,reg,basereg,indexreg,disp)        
\
+                       do { \
+                               x86_mov_memindex_reg((inst), (basereg), (disp), 
(indexreg), \
+                                                                        1, 
(reg), 2); \
+                       } while (0)
  
  #ifdef        __cplusplus

Index: unroll.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/unroll.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** unroll.c    10 Jul 2003 07:28:17 -0000      1.2
--- unroll.c    11 Jul 2003 00:58:25 -0000      1.3
***************
*** 25,28 ****
--- 25,29 ----
  #include "cvm_format.h"
  #include "il_dumpasm.h"
+ #include "lib_defs.h"
  
  #ifdef        __cplusplus
***************
*** 469,472 ****
--- 470,512 ----
  
  /*
+  * Check to see if the floating-point register array/stack is full.
+  * If it is, then flush the entire register stack.
+  */
+ static void CheckFPFull(MDUnroll *unroll)
+ {
+ #if MD_FP_STACK_SIZE != 0
+       /* Clear the cached local information */
+       unroll->cachedLocal = -1;
+       unroll->cachedReg = -1;
+ 
+       /* If the FPU stack is full, then flush and restart */
+       if(unroll->fpStackSize >= MD_FP_STACK_SIZE)
+       {
+               FlushRegisterStack(unroll);
+       }
+ #else
+       int index, reg, regmask;
+ 
+       /* Clear the cached local information */
+       unroll->cachedLocal = -1;
+       unroll->cachedReg = -1;
+ 
+       /* Search for an unused floating-point register */
+       for(index = 0; index < 16 && regAllocFPOrder[index] != -1; ++index)
+       {
+               reg = regAllocFPOrder[index];
+               regmask = (1 << reg);
+               if((unroll->regsUsed & regmask) == 0)
+               {
+                       return;
+               }
+       }
+ 
+       /* Flush the entire register stack */
+       FlushRegisterStack(unroll);
+ #endif
+ }
+ 
+ /*
   * Get a register that can be used to store floating-point values.
   */
***************
*** 521,524 ****
--- 561,579 ----
  
  /*
+  * Change the type of the top-most register on the stack.
+  */
+ static void ChangeRegisterType(MDUnroll *unroll, int type)
+ {
+       if((type & MD_REGN_NATIVE) != 0)
+       {
+               unroll->pseudoStack[unroll->pseudoStackSize - 1] |= 
MD_NATIVE_REG_MASK;
+       }
+       else
+       {
+               unroll->pseudoStack[unroll->pseudoStackSize - 1] &= 
~MD_NATIVE_REG_MASK;
+       }
+ }
+ 
+ /*
   * Get the top-most word value on the stack into a register.
   */
***************
*** 909,919 ****
  }
  
- #if 0
- 
  /*
   * Get the two top-most stack values in a word and an FP register.
-  * Returns the identifier for the word register.  The FP register is ST(0).
   */
! static int GetWordAndFPRegisters(X86Unroll *unroll)
  {
        /* Clear the cached local information */
--- 964,971 ----
  }
  
  /*
   * Get the two top-most stack values in a word and an FP register.
   */
! static void GetWordAndFPRegisters(MDUnroll *unroll, int *reg1, int *reg2)
  {
        /* Clear the cached local information */
***************
*** 922,968 ****
  
        /* Check for the expected information on the stack */
!       if(unroll->pseudoStackSize > 1 &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 2] != REG_FPU &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 1] == REG_FPU)
        {
!               return unroll->pseudoStack[unroll->pseudoStackSize - 2];
        }
  
!       /* If we have 1 FP value on the stack, then load the word into EAX */
!       if(unroll->pseudoStackSize == 1 &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 1] == REG_FPU)
        {
!               unroll->pseudoStack[0] = X86_EAX;
!               unroll->pseudoStack[1] = REG_FPU;
                unroll->pseudoStackSize = 2;
!               unroll->stackHeight -= 4;
!               x86_mov_reg_membase(unroll->out, X86_EAX, REG_STACK,
!                                                   unroll->stackHeight, 4);
!               unroll->regsUsed |= REG_EAX_MASK;
!               return X86_EAX;
        }
  
!       /* Flush the register stack and then reload into EAX and ST(0) */
        FlushRegisterStack(unroll);
!       unroll->pseudoStack[0] = X86_EAX;
!       unroll->pseudoStack[1] = REG_FPU;
        unroll->pseudoStackSize = 2;
!       unroll->stackHeight -= 16;
!       x86_mov_reg_membase(unroll->out, X86_EAX, REG_STACK,
!                                           unroll->stackHeight, 4);
!       x86_fld80_membase(unroll->out, REG_STACK, unroll->stackHeight + 4);
!       unroll->regsUsed |= REG_EAX_MASK;
        ++(unroll->fpStackSize);
!       return X86_EAX;
  }
  
  /*
   * Get the two top-most stack values in an FP and a word register.
-  * Returns the identifier for the word register.  The FP register is ST(0).
   */
! static int GetFPAndWordRegisters(MDUnroll *unroll)
  {
-       int reg;
- 
        /* Clear the cached local information */
        unroll->cachedLocal = -1;
--- 974,1028 ----
  
        /* Check for the expected information on the stack */
!       if(unroll->pseudoStackSize > 1)
        {
!               *reg1 = unroll->pseudoStack[unroll->pseudoStackSize - 2];
!               *reg2 = unroll->pseudoStack[unroll->pseudoStackSize - 1];
!               if(!MD_IS_FREG(*reg1) && MD_IS_FREG(*reg2))
!               {
!                       *reg1 &= ~MD_NATIVE_REG_MASK;
!                       return;
!               }
        }
  
!       /* If we have 1 FP value on the stack, then load the word into MD_REG_0 
*/
!       if(unroll->pseudoStackSize == 1 && MD_IS_FREG(unroll->pseudoStack[0]))
        {
!               *reg1 = MD_REG_0;
!               *reg2 = unroll->pseudoStack[0];
!               unroll->pseudoStack[0] = *reg1 | MD_NATIVE_REG_MASK;
!               unroll->pseudoStack[1] = *reg2;
                unroll->pseudoStackSize = 2;
!               unroll->stackHeight -= sizeof(CVMWord);
!               md_load_membase_word_native(unroll->out, MD_REG_0, MD_REG_STACK,
!                                                           
unroll->stackHeight);
!               unroll->regsUsed |= (1 << MD_REG_0);
!               return;
        }
  
!       /* Flush the register stack and then reload into MD_REG_0 and MD_FREG_0 
*/
        FlushRegisterStack(unroll);
!       *reg1 = MD_REG_0;
!       *reg2 = MD_FREG_0;
!       unroll->pseudoStack[0] = MD_REG_0 | MD_NATIVE_REG_MASK;
!       unroll->pseudoStack[1] = MD_FREG_0;
        unroll->pseudoStackSize = 2;
!       unroll->stackHeight -= (CVM_WORDS_PER_NATIVE_FLOAT + 1) * 
sizeof(CVMWord);
!       md_load_membase_word_native(unroll->out, MD_REG_0, MD_REG_STACK,
!                                                       unroll->stackHeight);
!       md_load_membase_float_native(unroll->out, MD_FREG_0, MD_REG_STACK,
!                                                                
unroll->stackHeight + sizeof(CVMWord));
!       unroll->regsUsed |= (1 << MD_REG_0);
! #if MD_FP_STACK_SIZE != 0
        ++(unroll->fpStackSize);
! #else
!       unroll->regsUsed |= (1 << MD_FREG_0);
! #endif
  }
  
  /*
   * Get the two top-most stack values in an FP and a word register.
   */
! static void GetFPAndWordRegisters(MDUnroll *unroll, int *reg1, int *reg2)
  {
        /* Clear the cached local information */
        unroll->cachedLocal = -1;
***************
*** 970,1009 ****
  
        /* Check for the expected information on the stack */
!       if(unroll->pseudoStackSize > 1 &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 2] == REG_FPU &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 1] != REG_FPU)
        {
!               return unroll->pseudoStack[unroll->pseudoStackSize - 1];
        }
  
!       /* If we have 1 word value on the stack, then load the FP into ST(0) */
!       if(unroll->pseudoStackSize == 1 &&
!          unroll->pseudoStack[unroll->pseudoStackSize - 1] != REG_FPU)
        {
!               reg = unroll->pseudoStack[0];
!               unroll->pseudoStack[0] = REG_FPU;
!               unroll->pseudoStack[1] = reg;
                unroll->pseudoStackSize = 2;
!               unroll->stackHeight -= 12;
!               x86_fld80_membase(unroll->out, REG_STACK, unroll->stackHeight);
                ++(unroll->fpStackSize);
!               return reg;
        }
  
!       /* Flush the register stack and then reload into ST(0) and EAX */
        FlushRegisterStack(unroll);
!       unroll->pseudoStack[0] = REG_FPU;
!       unroll->pseudoStack[1] = X86_EAX;
        unroll->pseudoStackSize = 2;
!       unroll->stackHeight -= 16;
!       x86_fld80_membase(unroll->out, REG_STACK, unroll->stackHeight);
!       x86_mov_reg_membase(unroll->out, X86_EAX, REG_STACK,
!                                           unroll->stackHeight + 12, 4);
!       unroll->regsUsed |= REG_EAX_MASK;
        ++(unroll->fpStackSize);
!       return X86_EAX;
! }
! 
  #endif
  
  #endif /* MD_HAS_FP */
--- 1030,1084 ----
  
        /* Check for the expected information on the stack */
!       if(unroll->pseudoStackSize > 1)
        {
!               *reg1 = unroll->pseudoStack[unroll->pseudoStackSize - 2];
!               *reg2 = unroll->pseudoStack[unroll->pseudoStackSize - 1];
!               if(MD_IS_FREG(*reg1) && !MD_IS_FREG(*reg2))
!               {
!                       *reg2 &= ~MD_NATIVE_REG_MASK;
!                       return;
!               }
        }
  
!       /* If we have 1 word value on the stack, then load the FP into 
MD_FREG_0 */
!       if(unroll->pseudoStackSize == 1 && !MD_IS_FREG(unroll->pseudoStack[0]))
        {
!               *reg1 = unroll->pseudoStack[0];
!               *reg2 = MD_FREG_0;
!               unroll->pseudoStack[0] = *reg1;
!               unroll->pseudoStack[1] = *reg2 | MD_NATIVE_REG_MASK;
                unroll->pseudoStackSize = 2;
!               unroll->stackHeight -= CVM_WORDS_PER_NATIVE_FLOAT * 
sizeof(CVMWord);
!               md_load_membase_float_native(unroll->out, MD_FREG_0, 
MD_REG_STACK,
!                                                            
unroll->stackHeight);
!       #if MD_FP_STACK_SIZE != 0
                ++(unroll->fpStackSize);
!       #else
!               unroll->regsUsed |= (1 << MD_FREG_0);
!       #endif
!               return;
        }
  
!       /* Flush the register stack and then reload into MD_FREG_0 and MD_REG_0 
*/
        FlushRegisterStack(unroll);
!       *reg1 = MD_FREG_0;
!       *reg2 = MD_REG_0;
!       unroll->pseudoStack[0] = MD_FREG_0;
!       unroll->pseudoStack[1] = MD_REG_0 | MD_NATIVE_REG_MASK;
        unroll->pseudoStackSize = 2;
!       unroll->stackHeight -= (CVM_WORDS_PER_NATIVE_FLOAT + 1) * 
sizeof(CVMWord);
!       md_load_membase_float_native(unroll->out, MD_FREG_0, MD_REG_STACK,
!                                                                
unroll->stackHeight);
!       md_load_membase_word_native(unroll->out, MD_REG_0, MD_REG_STACK,
!                                                       unroll->stackHeight +
!                                                                       
CVM_WORDS_PER_NATIVE_FLOAT *
!                                                                       
sizeof(CVMWord));
!       unroll->regsUsed |= (1 << MD_REG_0);
! #if MD_FP_STACK_SIZE != 0
        ++(unroll->fpStackSize);
! #else
!       unroll->regsUsed |= (1 << MD_FREG_0);
  #endif
+ }
  
  #endif /* MD_HAS_FP */
***************
*** 1280,1286 ****
  #include "unroll_arith.c"
  //#include "unroll_branch.c"
! //#include "unroll_const.c"
  //#include "unroll_conv.c"
! //#include "unroll_ptr.c"
  #include "unroll_var.c"
  #undef        IL_UNROLL_GLOBAL
--- 1355,1361 ----
  #include "unroll_arith.c"
  //#include "unroll_branch.c"
! #include "unroll_const.c"
  //#include "unroll_conv.c"
! #include "unroll_ptr.c"
  #include "unroll_var.c"
  #undef        IL_UNROLL_GLOBAL
***************
*** 1362,1368 ****
                        #include "unroll_arith.c"
                        //#include "unroll_branch.c"
!                       //#include "unroll_const.c"
                        //#include "unroll_conv.c"
!                       //#include "unroll_ptr.c"
                        #include "unroll_var.c"
                        #undef  IL_UNROLL_CASES
--- 1437,1443 ----
                        #include "unroll_arith.c"
                        //#include "unroll_branch.c"
!                       #include "unroll_const.c"
                        //#include "unroll_conv.c"
!                       #include "unroll_ptr.c"
                        #include "unroll_var.c"
                        #undef  IL_UNROLL_CASES





reply via email to

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