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_branch.c, NONE, 1.1 unroll


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/engine unroll_branch.c, NONE, 1.1 unroll_conv.c, NONE, 1.1 md_arm.h, 1.3, 1.4 md_x86.c, 1.2, 1.3 md_x86.h, 1.3, 1.4 unroll.c, 1.3, 1.4
Date: Thu, 10 Jul 2003 23:32:34 -0400

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

Modified Files:
        md_arm.h md_x86.c md_x86.h unroll.c 
Added Files:
        unroll_branch.c unroll_conv.c 
Log Message:


Implement generic unrolling for branch and conversion opcodes.


--- NEW FILE ---
/*
 * unroll_branch.c - Branch 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

/*
 * Perform a conditional branch to one of two program locations.
 * It is assumed that "cond" refers to the inverse of the condition
 * that we are really testing.
 */
static void BranchOnCondition(MDUnroll *unroll, int cond,
                                                      unsigned char *truePC,
                                                          unsigned char 
*falsePC)
{
        md_inst_ptr patch;

        /* Flush the registers and restore special values.  Because this only
           uses "mov" and "pop" operations, it will not affect the flags */
        FlushRegisterStack(unroll);
        RestoreSpecialRegisters(unroll);
        unroll->regsSaved = 0;

        /* Test the condition in such a way that we branch if false */
        patch = unroll->out;
        md_branch_cc(unroll->out, cond);

        /* Output the jump to the true PC */
        FixStackHeight(unroll);
        UnloadMachineState(unroll, truePC, 0);

        /* Back-patch the branch instruction to point here */
        md_patch(patch, unroll->out);

        /* Output the jump to the false PC */
        FixStackHeight(unroll);
        unroll->stackHeight = 0;
        UnloadMachineState(unroll, falsePC, 0);
}

#elif defined(IL_UNROLL_CASES)

case COP_BR:
{
        /* Branch unconditionally to a destination */
        UNROLL_BRANCH_START();
        BranchToPC(&unroll, CVM_ARG_BRANCH_SHORT);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BEQ:
{
        /* Branch if two words are equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_NE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BR_PEQ:
{
        /* Branch if two native words are equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_cmp_cc_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_NE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BNE:
{
        /* Branch if two words are not equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_EQ,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BR_PNE:
{
        /* Branch if two native words are not equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_NATIVE | 
MD_REG2_NATIVE);
        md_cmp_cc_reg_reg_word_native(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_EQ,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BLT:
{
        /* Branch if less than */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_GE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BLT_UN:
{
        /* Branch if unsigned less than */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_GE_UN,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BLE:
{
        /* Branch if less than or equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_GT,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BLE_UN:
{
        /* Branch if unsigned less than or equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_GT_UN,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BGT:
{
        /* Branch if greater than */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_LE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BGT_UN:
{
        /* Branch if unsigned greater than */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_LE_UN,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BGE:
{
        /* Branch if greater than or equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_LT,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BGE_UN:
{
        /* Branch if unsigned greater than or equal */
        UNROLL_BRANCH_START();
        GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                                                   MD_REG1_32BIT | 
MD_REG2_32BIT);
        md_cmp_cc_reg_reg_word_32(unroll.out, reg, reg2);
        FreeTopRegister(&unroll, -1);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_LT_UN,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BRTRUE:
{
        /* Branch if non-zero */
        UNROLL_BRANCH_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_is_zero(unroll.out, reg);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_EQ,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BRNONNULL:
{
        /* Branch if non-null */
        UNROLL_BRANCH_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_reg_is_null(unroll.out, reg);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_EQ,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BRFALSE:
{
        /* Branch if zero */
        UNROLL_BRANCH_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_is_zero(unroll.out, reg);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_NE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_BRNULL:
{
        /* Branch if null */
        UNROLL_BRANCH_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_NATIVE);
        md_reg_is_null(unroll.out, reg);
        FreeTopRegister(&unroll, -1);
        BranchOnCondition(&unroll, MD_CC_NE,
                                          CVM_ARG_BRANCH_SHORT, pc + 
CVM_LEN_BRANCH);
        MODIFY_UNROLL_PC(CVM_LEN_BRANCH);
        UNROLL_FLUSH();
}
break;

case COP_SWITCH:
{
        /* Switch statement */
        md_inst_ptr patch;
        UNROLL_BRANCH_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        FreeTopRegister(&unroll, -1);
        FlushRegisterStack(&unroll);
        if((MD_REGS_TO_BE_SAVED & (1 << reg)) != 0)
        {
                /* Shift the value into MD_REG_0 so that it won't
                   get clobbered by "RestoreSpecialRegisters" below */
                md_mov_reg_reg(unroll.out, MD_REG_0, reg);
                reg = MD_REG_0;
        }
        md_cmp_reg_imm_word_32(unroll.out, reg, CVM_ARG_SWITCH_LIMIT);
        patch = unroll.out;
        md_branch_ge_un(unroll.out);
        FixStackHeight(&unroll);
        RestoreSpecialRegisters(&unroll);
        md_switch(unroll.out, reg, pc + 3 * sizeof(void *));
        md_patch(patch, unroll.out);
        BranchToPC(&unroll, CVM_ARG_SWITCH_DEFAULT);
        pc = CVM_ARG_SWITCH_DEFAULT;
        UNROLL_FLUSH();
}
break;

#endif /* IL_UNROLL_CASES */

--- NEW FILE ---
/*
 * unroll_conv.c - Conversion 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_I2B:
{
        /* Convert an integer into a byte */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_to_sbyte(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_I2UB:
{
        /* Convert an integer into an unsigned byte */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_to_byte(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_I2S:
{
        /* Convert an integer into a short */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_to_short(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_I2US:
{
        /* Convert an integer into an unsigned short */
        UNROLL_START();
        reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
        md_reg_to_ushort(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#ifdef MD_HAS_FP

case COP_F2F:
{
        /* Truncate a floating point value to float32 */
        UNROLL_START();
        reg = GetTopFPRegister(&unroll);
        md_reg_to_float_32(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

case COP_F2D:
{
        /* Truncate a floating point value to float64 */
        UNROLL_START();
        reg = GetTopFPRegister(&unroll);
        md_reg_to_float_64(unroll.out, reg);
        MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;

#endif /* MD_HAS_FP */

#endif /* IL_UNROLL_CASES */

Index: md_arm.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_arm.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** md_arm.h    11 Jul 2003 00:58:25 -0000      1.3
--- md_arm.h    11 Jul 2003 03:32:32 -0000      1.4
***************
*** 414,417 ****
--- 414,428 ----
  
  /*
+  * Jump to a program counter that is defined by a switch table.
+  */
+ #define       md_switch(inst,reg,table)       \
+                       do { \
+                               arm_load_membase((inst), ARM_WORK, ARM_PC, 4); \
+                               arm_load_memindex((inst), MD_REG_PC, ARM_WORK, 
(reg)); \
+                               arm_load_membase((inst), ARM_PC, MD_REG_PC, 0); 
\
+                               *((inst)++) = (unsigned int)(table); \
+                       } while (0)
+ 
+ /*
   * Perform a clear operation at a memory base.
   */
***************
*** 490,493 ****
--- 501,512 ----
  
  /*
+  * Set the condition codes based on comparing two values.
+  */
+ #define       md_cmp_cc_reg_reg_word_32(inst,reg1,reg2)       \
+                       arm_test_reg_reg((inst), ARM_CMP, (reg1), (reg2))
+ #define       md_cmp_cc_reg_reg_word_native(inst,reg1,reg2)   \
+                       arm_test_reg_reg((inst), ARM_CMP, (reg1), (reg2))
+ 
+ /*
   * Test the contents of a register against NULL and set the
   * condition codes based on the result.
***************
*** 497,500 ****
--- 516,526 ----
  
  /*
+  * Test the contents of a register against 32-bit zero and set the
+  * condition codes based on the result.
+  */
+ #define       md_reg_is_zero(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.
***************
*** 520,523 ****
--- 546,565 ----
  #define       md_branch_ge_un(inst)   \
                        arm_branch_imm((inst), ARM_CC_GE_UN, 0)
+ #define       md_branch_cc(inst,cond) \
+                       arm_branch_imm((inst), (cond), 0)
+ 
+ /*
+  * Specific condition codes for "md_branch_cc".
+  */
+ #define       MD_CC_EQ                                ARM_CC_EQ
+ #define       MD_CC_NE                                ARM_CC_NE
+ #define       MD_CC_LT                                ARM_CC_LT
+ #define       MD_CC_LE                                ARM_CC_LE
+ #define       MD_CC_GT                                ARM_CC_GT
+ #define       MD_CC_GE                                ARM_CC_GE
+ #define       MD_CC_LT_UN                             ARM_CC_LT_UN
+ #define       MD_CC_LE_UN                             ARM_CC_LE_UN
+ #define       MD_CC_GT_UN                             ARM_CC_GT_UN
+ #define       MD_CC_GE_UN                             ARM_CC_GE_UN
  
  /*

Index: md_x86.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** md_x86.c    11 Jul 2003 00:58:25 -0000      1.2
--- md_x86.c    11 Jul 2003 03:32:32 -0000      1.3
***************
*** 184,187 ****
--- 184,203 ----
  }
  
+ md_inst_ptr _md_x86_widen_byte(md_inst_ptr inst, int reg, int isSigned)
+ {
+       if(reg == X86_EAX || reg == X86_EBX || reg == X86_ECX || reg == X86_EDX)
+       {
+               x86_widen_reg(inst, reg, reg, isSigned, 0);
+       }
+       else
+       {
+               x86_push_reg(inst, X86_EAX);
+               x86_mov_reg_reg(inst, X86_EAX, reg, 4);
+               x86_widen_reg(inst, reg, X86_EAX, isSigned, 0);
+               x86_pop_reg(inst, X86_EAX);
+       }
+       return inst;
+ }
+ 
  #ifdef        __cplusplus
  };

Index: md_x86.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** md_x86.h    11 Jul 2003 00:58:25 -0000      1.3
--- md_x86.h    11 Jul 2003 03:32:32 -0000      1.4
***************
*** 379,386 ****
   * Convert word registers between various types.
   */
  #define       md_reg_to_byte(inst,reg)        \
!                       x86_widen_reg((inst), (reg), (reg), 0, 0)
  #define       md_reg_to_sbyte(inst,reg)       \
!                       x86_widen_reg((inst), (reg), (reg), 1, 0)
  #define       md_reg_to_short(inst,reg)       \
                        x86_widen_reg((inst), (reg), (reg), 1, 1)
--- 379,391 ----
   * Convert word registers between various types.
   */
+ extern md_inst_ptr _md_x86_widen_byte(md_inst_ptr inst, int reg, int 
isSigned);
  #define       md_reg_to_byte(inst,reg)        \
!                       do { \
!                               (inst) = _md_x86_widen_byte((inst), (reg), 0); \
!                       } while (0)
  #define       md_reg_to_sbyte(inst,reg)       \
!                       do { \
!                               (inst) = _md_x86_widen_byte((inst), (reg), 1); \
!                       } while (0)
  #define       md_reg_to_short(inst,reg)       \
                        x86_widen_reg((inst), (reg), (reg), 1, 1)
***************
*** 436,439 ****
--- 441,454 ----
  
  /*
+  * Jump to a program counter that is defined by a switch table.
+  */
+ #define       md_switch(inst,reg,table)       \
+                       do { \
+                               x86_mov_reg_memindex((inst), MD_REG_PC, 
X86_NOBASEREG, \
+                                                                        
(int)(table), (reg), 2, 4); \
+                               x86_jump_membase((inst), MD_REG_PC, 0); \
+                       } while (0)
+ 
+ /*
   * Perform a clear operation at a memory base.
   */
***************
*** 496,499 ****
--- 511,522 ----
  
  /*
+  * Set the condition codes based on comparing two values.
+  */
+ #define       md_cmp_cc_reg_reg_word_32(inst,reg1,reg2)       \
+                       x86_alu_reg_reg((inst), X86_CMP, (reg1), (reg2))
+ #define       md_cmp_cc_reg_reg_word_native(inst,reg1,reg2)   \
+                       x86_alu_reg_reg((inst), X86_CMP, (reg1), (reg2))
+ 
+ /*
   * Test the contents of a register against NULL and set the
   * condition codes based on the result.
***************
*** 503,506 ****
--- 526,543 ----
  
  /*
+  * Test the contents of a register against 32-bit zero and set the
+  * condition codes based on the result.
+  */
+ #define       md_reg_is_zero(inst,reg)        \
+                       x86_alu_reg_reg((inst), X86_OR, (reg), (reg))
+ 
+ /*
+  * Compare a 32-bit register against an immediate value and set
+  * the condition codes based on the result.
+  */
+ #define       md_cmp_reg_imm_word_32(inst,reg,imm)    \
+                       x86_alu_reg_imm((inst), X86_CMP, (reg), (int)(imm))
+ 
+ /*
   * Output a branch to a location based on a condition.  The actual
   * jump offset will be filled in by a later "md_patch" call.
***************
*** 526,529 ****
--- 563,582 ----
  #define       md_branch_ge_un(inst)   \
                        x86_branch32((inst), X86_CC_GE, 0, 0)
+ #define       md_branch_cc(inst,cond) \
+                       x86_branch32((inst), (cond) & 15, 0, ((cond) & 16) != 0)
+ 
+ /*
+  * Specific condition codes for "md_branch_cc".
+  */
+ #define       MD_CC_EQ                                X86_CC_EQ
+ #define       MD_CC_NE                                X86_CC_NE
+ #define       MD_CC_LT                                (X86_CC_LT | 16)
+ #define       MD_CC_LE                                (X86_CC_LE | 16)
+ #define       MD_CC_GT                                (X86_CC_GT | 16)
+ #define       MD_CC_GE                                (X86_CC_GE | 16)
+ #define       MD_CC_LT_UN                             X86_CC_LT
+ #define       MD_CC_LE_UN                             X86_CC_LE
+ #define       MD_CC_GT_UN                             X86_CC_GT
+ #define       MD_CC_GE_UN                             X86_CC_GE
  
  /*
***************
*** 566,570 ****
                        do { \
                                x86_widen_memindex((inst), (reg), (basereg), \
!                                                                  (disp), 
(indexreg), 0, 1, 0); \
                        } while (0)
  
--- 619,623 ----
                        do { \
                                x86_widen_memindex((inst), (reg), (basereg), \
!                                                                  (disp), 
(indexreg), 0, 0, 0); \
                        } while (0)
  
***************
*** 575,579 ****
                        do { \
                                x86_widen_memindex((inst), (reg), (basereg), \
!                                                                  (disp), 
(indexreg), 0, 0, 0); \
                        } while (0)
  
--- 628,632 ----
                        do { \
                                x86_widen_memindex((inst), (reg), (basereg), \
!                                                                  (disp), 
(indexreg), 0, 1, 0); \
                        } while (0)
  

Index: unroll.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/unroll.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** unroll.c    11 Jul 2003 00:58:25 -0000      1.3
--- unroll.c    11 Jul 2003 03:32:32 -0000      1.4
***************
*** 207,210 ****
--- 207,226 ----
  }
  
+ /*
+  * Restore special registers that were saved during execution.
+  */
+ static void RestoreSpecialRegisters(MDUnroll *unroll)
+ {
+       int index, reg;
+       for(index = 15; index >= 0; --index)
+       {
+               reg = regAllocOrder[index];
+               if(reg != -1 && (unroll->regsSaved & (1 << reg)) != 0)
+               {
+                       md_pop_reg(unroll->out, reg);
+               }
+       }
+ }
+ 
  #if !MD_STATE_ALREADY_IN_REGS
  
***************
*** 274,279 ****
  static void BranchToPC(MDUnroll *unroll, unsigned char *pc)
  {
-       int index, reg;
- 
        /* Flush the register stack to the CVM stack */
        FlushRegisterStack(unroll);
--- 290,293 ----
***************
*** 284,295 ****
  
        /* Restore the special registers that we used */
!       for(index = 15; index >= 0; --index)
!       {
!               reg = regAllocOrder[index];
!               if(reg != -1 && (unroll->regsSaved & (1 << reg)) != 0)
!               {
!                       md_pop_reg(unroll->out, reg);
!               }
!       }
        unroll->regsSaved = 0;
  
--- 298,302 ----
  
        /* Restore the special registers that we used */
!       RestoreSpecialRegisters(unroll);
        unroll->regsSaved = 0;
  
***************
*** 305,309 ****
                                          unsigned char *label)
  {
!       int index, reg, finalHeight;
  
        /* Flush the register stack, but don't change it as we will
--- 312,316 ----
                                          unsigned char *label)
  {
!       int finalHeight;
  
        /* Flush the register stack, but don't change it as we will
***************
*** 322,333 ****
  
        /* Restore the saved special registers */
!       for(index = 15; index >= 0; --index)
!       {
!               reg = regAllocOrder[index];
!               if(reg != -1 && (unroll->regsSaved & (1 << reg)) != 0)
!               {
!                       md_pop_reg(unroll->out, reg);
!               }
!       }
  
        /* Jump into the CVM interpreter to re-execute the instruction */
--- 329,333 ----
  
        /* Restore the saved special registers */
!       RestoreSpecialRegisters(unroll);
  
        /* Jump into the CVM interpreter to re-execute the instruction */
***************
*** 1354,1360 ****
  #define       IL_UNROLL_GLOBAL
  #include "unroll_arith.c"
! //#include "unroll_branch.c"
  #include "unroll_const.c"
! //#include "unroll_conv.c"
  #include "unroll_ptr.c"
  #include "unroll_var.c"
--- 1354,1360 ----
  #define       IL_UNROLL_GLOBAL
  #include "unroll_arith.c"
! #include "unroll_branch.c"
  #include "unroll_const.c"
! #include "unroll_conv.c"
  #include "unroll_ptr.c"
  #include "unroll_var.c"
***************
*** 1436,1442 ****
                        #define IL_UNROLL_CASES
                        #include "unroll_arith.c"
!                       //#include "unroll_branch.c"
                        #include "unroll_const.c"
!                       //#include "unroll_conv.c"
                        #include "unroll_ptr.c"
                        #include "unroll_var.c"
--- 1436,1442 ----
                        #define IL_UNROLL_CASES
                        #include "unroll_arith.c"
!                       #include "unroll_branch.c"
                        #include "unroll_const.c"
!                       #include "unroll_conv.c"
                        #include "unroll_ptr.c"
                        #include "unroll_var.c"





reply via email to

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