[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnet/engine md_arm.c, NONE, 1.1 md_x86.c, NO
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnet/engine md_arm.c, NONE, 1.1 md_x86.c, NONE, 1.1 unroll_arith.c, NONE, 1.1 md_arm.h, 1.1, 1.2 md_default.h, 1.1, 1.2 md_x86.h, 1.1, 1.2 unroll.c, 1.1, 1.2 |
Date: |
Thu, 10 Jul 2003 03:28:20 -0400 |
Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv16685/engine
Modified Files:
md_arm.h md_default.h md_x86.h unroll.c
Added Files:
md_arm.c md_x86.c unroll_arith.c
Log Message:
Add some more code to the generic unroller.
--- NEW FILE ---
/*
* md_arm.c - Machine-dependent definitions for ARM.
*
* Copyright (C) 2003 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "md_arm.h"
#ifdef __cplusplus
extern "C" {
#endif
arm_inst_ptr _arm_mov_reg_imm(arm_inst_ptr inst, int reg, int value)
{
/* Handle bytes in various positions */
if((value & 0x000000FF) == value)
{
arm_mov_reg_imm8(inst, reg, value);
return inst;
}
else if((value & 0x0000FF00) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
return inst;
}
else if((value & 0x00FF0000) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
return inst;
}
else if((value & 0xFF000000) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
return inst;
}
/* Handle inverted bytes in various positions */
value = ~value;
if((value & 0x000000FF) == value)
{
arm_mov_reg_imm8(inst, reg, value);
arm_alu_reg(inst, ARM_MVN, reg, reg);
return inst;
}
else if((value & 0x0000FF00) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
arm_alu_reg(inst, ARM_MVN, reg, reg);
return inst;
}
else if((value & 0x00FF0000) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
arm_alu_reg(inst, ARM_MVN, reg, reg);
return inst;
}
else if((value & 0xFF000000) == value)
{
arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
arm_alu_reg(inst, ARM_MVN, reg, reg);
return inst;
}
/* Build the value the hard way, byte by byte */
value = ~value;
if((value & 0xFF000000) != 0)
{
arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
if((value & 0x00FF0000) != 0)
{
arm_alu_reg_imm8_rotate
(inst, ARM_ADD, reg, reg, ((value >> 16) &
0xFF), 8);
}
if((value & 0x0000FF00) != 0)
{
arm_alu_reg_imm8_rotate
(inst, ARM_ADD, reg, reg, ((value >> 8) &
0xFF), 12);
}
if((value & 0x000000FF) != 0)
{
arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
}
}
else if((value & 0x00FF0000) != 0)
{
arm_mov_reg_imm8_rotate(inst, reg, ((value >> 16) & 0xFF), 8);
if((value & 0x0000FF00) != 0)
{
arm_alu_reg_imm8_rotate
(inst, ARM_ADD, reg, reg, ((value >> 8) &
0xFF), 12);
}
if((value & 0x000000FF) != 0)
{
arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
}
}
else if((value & 0x0000FF00) != 0)
{
arm_mov_reg_imm8_rotate(inst, reg, ((value >> 8) & 0xFF), 12);
if((value & 0x000000FF) != 0)
{
arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
}
}
else
{
arm_mov_reg_imm8(inst, reg, (value & 0xFF));
}
return inst;
}
arm_inst_ptr _arm_alu_reg_imm(arm_inst_ptr inst, int opc,
int dreg, int sreg, int imm,
int saveWork)
{
int tempreg;
if(saveWork)
{
if(dreg != ARM_R2 && sreg != ARM_R2)
{
tempreg = ARM_R2;
}
else if(dreg != ARM_R3 && sreg != ARM_R3)
{
tempreg = ARM_R3;
}
else
{
tempreg = ARM_R4;
}
arm_push_reg(inst, tempreg);
}
else
{
tempreg = ARM_WORK;
}
_arm_mov_reg_imm(inst, tempreg, imm);
arm_alu_reg_reg(inst, opc, dreg, sreg, tempreg);
if(saveWork)
{
arm_pop_reg(inst, tempreg);
}
return inst;
}
md_inst_ptr _md_arm_setcc(md_inst_ptr inst, int reg, int cond, int invcond)
{
arm_test_reg_imm8(inst, ARM_CMP, reg, 0);
arm_alu_reg_imm8_cond(inst, ARM_MOV, reg, 0, 1, cond);
arm_alu_reg_imm8_cond(inst, ARM_MOV, reg, 0, 0, invcond);
return inst;
}
#ifdef __cplusplus
};
#endif
--- NEW FILE ---
/*
* md_x86.c - Machine-dependent definitions for x86.
*
* Copyright (C) 2003 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "md_x86.h"
#ifdef __cplusplus
extern "C" {
#endif
md_inst_ptr _md_x86_shift(md_inst_ptr inst, int opc, int reg1, int reg2)
{
if(reg2 == X86_ECX)
{
/* The shift value is already in ECX */
x86_shift_reg(inst, opc, reg1);
}
else if(reg1 == X86_ECX)
{
/* The value to be shifted is in ECX, so swap the order */
x86_xchg_reg_reg(inst, reg1, reg2, 4);
x86_shift_reg(inst, opc, reg2);
x86_mov_reg_reg(inst, reg1, reg2, 4);
}
else
{
/* Save ECX, perform the shift, and then restore ECX */
x86_push_reg(inst, X86_ECX);
x86_mov_reg_reg(inst, X86_ECX, reg2, 4);
x86_shift_reg(inst, opc, reg1);
x86_pop_reg(inst, X86_ECX);
}
return inst;
}
md_inst_ptr _md_x86_mov_membase_reg_byte
(md_inst_ptr inst, int basereg, int offset, int srcreg)
{
if(srcreg == X86_EAX || srcreg == X86_EBX ||
srcreg == X86_ECX || srcreg == X86_EDX)
{
x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
}
else if(basereg != X86_EAX)
{
x86_push_reg(inst, X86_EAX);
x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
x86_pop_reg(inst, X86_EAX);
}
else
{
x86_push_reg(inst, X86_EDX);
x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
x86_pop_reg(inst, X86_EDX);
}
return inst;
}
md_inst_ptr _md_x86_rem_float
(md_inst_ptr inst, int reg1, int reg2, int used)
{
md_inst_ptr label;
if((used & (1 << X86_EAX)) != 0)
{
x86_push_reg(inst, X86_EAX);
}
label = inst;
x86_fprem1(inst);
x86_fnstsw(inst);
x86_alu_reg_imm(inst, X86_AND, X86_EAX, 0x0400);
x86_branch(inst, X86_CC_NZ, label, 0);
x86_fstp(inst, 1);
if((used & (1 << X86_EAX)) != 0)
{
x86_pop_reg(inst, X86_EAX);
}
return inst;
}
md_inst_ptr _md_x86_setcc(md_inst_ptr inst, int reg, int cond)
{
if(cond == X86_CC_EQ || cond == X86_CC_NE)
{
x86_alu_reg_reg(inst, X86_OR, reg, reg);
}
else
{
x86_alu_reg_imm(inst, X86_CMP, reg, 0);
}
if(reg == X86_EAX || reg == X86_EBX || reg == X86_ECX || reg == X86_EDX)
{
/* Use a SETcc instruction if we have a basic register */
x86_set_reg(inst, cond, reg, 1);
x86_widen_reg(inst, reg, reg, 0, 0);
}
else
{
/* The register is not useable as an 8-bit destination */
unsigned char *patch1, *patch2;
patch1 = inst;
x86_branch8(inst, cond, 0, 1);
x86_clear_reg(inst, reg);
patch2 = inst;
x86_jump8(inst, 0);
x86_patch(patch1, inst);
x86_mov_reg_imm(inst, reg, 1);
x86_patch(patch2, inst);
}
return inst;
}
md_inst_ptr _md_x86_compare(md_inst_ptr inst, int reg1, int reg2, int isSigned)
{
unsigned char *patch1, *patch2, *patch3;
x86_alu_reg_reg(inst, X86_CMP, reg1, reg2);
patch1 = inst;
x86_branch8(inst, X86_CC_GE, 0, isSigned);
x86_mov_reg_imm(inst, reg1, -1);
patch2 = inst;
x86_jump8(inst, 0);
x86_patch(patch1, inst);
patch1 = inst;
x86_branch8(inst, X86_CC_EQ, 0, 0);
x86_mov_reg_imm(inst, reg1, 1);
patch3 = inst;
x86_jump8(inst, 0);
x86_patch(patch1, inst);
x86_clear_reg(inst, reg1);
x86_patch(patch2, inst);
x86_patch(patch3, inst);
return inst;
}
#ifdef __cplusplus
};
#endif
--- NEW FILE ---
/*
* unroll_arith.c - Arithmetic handling for generic CVM unrolling.
*
* Copyright (C) 2003 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef IL_UNROLL_GLOBAL
#ifdef CVM_X86
/*
* Perform an integer division or remainder.
*/
static void X86Divide(MDUnroll *unroll, int isSigned, int wantRemainder,
unsigned char *pc, unsigned char *label)
{
unsigned char *patch1, *patch2, *patch3;
/* Get the arguments into EAX and ECX so we know where they are */
if(unroll->pseudoStackSize != 2 ||
unroll->pseudoStack[0] != X86_EAX ||
unroll->pseudoStack[1] != X86_ECX)
{
FlushRegisterStack(unroll);
unroll->stackHeight -= 8;
x86_mov_reg_membase(unroll->out, X86_EAX, MD_REG_STACK,
unroll->stackHeight, 4);
x86_mov_reg_membase(unroll->out, X86_ECX, MD_REG_STACK,
unroll->stackHeight +
4, 4);
unroll->pseudoStack[0] = X86_EAX;
unroll->pseudoStack[1] = X86_ECX;
unroll->pseudoStackSize = 2;
unroll->regsUsed |= ((1 << X86_EAX) | (1 << X86_ECX));
}
/* Check for conditions that may cause an exception */
x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, 0);
patch1 = unroll->out;
x86_branch8(unroll->out, X86_CC_EQ, 0, 0);
x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, -1);
patch2 = unroll->out;
x86_branch32(unroll->out, X86_CC_NE, 0, 0);
x86_alu_reg_imm(unroll->out, X86_CMP, X86_EAX, (int)0x80000000);
patch3 = unroll->out;
x86_branch32(unroll->out, X86_CC_NE, 0, 0);
x86_patch(patch1, unroll->out);
/* Re-execute the division instruction to throw the exception */
ReExecute(unroll, pc, label);
/* Perform the division */
x86_patch(patch2, unroll->out);
x86_patch(patch3, unroll->out);
if(isSigned)
{
x86_cdq(unroll->out);
}
else
{
x86_clear_reg(unroll->out, X86_EDX);
}
x86_div_reg(unroll->out, X86_ECX, isSigned);
/* Pop ECX from the pseudo stack */
FreeTopRegister(unroll, -1);
/* If we want the remainder, then replace EAX with EDX on the stack */
if(wantRemainder)
{
unroll->pseudoStack[0] = X86_EDX;
unroll->regsUsed = (1 << X86_EDX);
}
}
#endif /* CVM_X86 */
#elif defined(IL_UNROLL_CASES)
case COP_IADD:
{
/* Add integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_add_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_ISUB:
{
/* Subtract integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_sub_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IMUL:
{
/* Multiply integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_mul_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
#ifdef CVM_X86
case COP_IDIV:
{
/* Divide integers */
UNROLL_START();
X86Divide(&unroll, 1, 0, pc, (unsigned char *)inst);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IDIV_UN:
{
/* Divide unsigned integers */
UNROLL_START();
X86Divide(&unroll, 0, 0, pc, (unsigned char *)inst);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IREM:
{
/* Remainder integers */
UNROLL_START();
X86Divide(&unroll, 1, 1, pc, (unsigned char *)inst);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IREM_UN:
{
/* Remainder unsigned integers */
UNROLL_START();
X86Divide(&unroll, 0, 1, pc, (unsigned char *)inst);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
#endif /* CVM_X86 */
case COP_INEG:
{
/* Negate integer */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_neg_reg_word_32(unroll.out, reg);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
#ifdef MD_HAS_FP
case COP_FADD:
{
/* Add floating point */
UNROLL_START();
GetTopTwoFPRegisters(&unroll, ®, ®2, 0);
md_add_reg_reg_float(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_FSUB:
{
/* Subtract floating point */
UNROLL_START();
GetTopTwoFPRegisters(&unroll, ®, ®2, 0);
md_sub_reg_reg_float(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_FMUL:
{
/* Multiply floating point */
UNROLL_START();
GetTopTwoFPRegisters(&unroll, ®, ®2, 0);
md_mul_reg_reg_float(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_FDIV:
{
/* Divide floating point */
UNROLL_START();
GetTopTwoFPRegisters(&unroll, ®, ®2, 0);
md_div_reg_reg_float(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_FREM:
{
/* Remainder floating point */
UNROLL_START();
GetTopTwoFPRegisters(&unroll, ®, ®2, 1);
md_rem_reg_reg_float(unroll.out, reg, reg2, unroll.regsUsed);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_FNEG:
{
/* Negate floating point */
UNROLL_START();
reg = GetTopFPRegister(&unroll);
md_neg_reg_float(unroll.out, reg);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
#endif /* MD_HAS_FP */
case COP_IAND:
{
/* Bitwise and integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_and_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IOR:
{
/* Bitwise or integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_or_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_IXOR:
{
/* Bitwise xor integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_xor_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_INOT:
{
/* Bitwise not integer */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_not_reg_word_32(unroll.out, reg);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_ISHL:
{
/* Left shift integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_shl_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_ISHR:
{
/* Right shift integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_shr_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case COP_ISHR_UN:
{
/* Unsigned right shift integers */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_ushr_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVM_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_ICMP:
{
/* Compare integer values with -1, 0, or 1 result */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_cmp_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_ICMP_UN:
{
/* Compare unsigned integer values with -1, 0, or 1 result */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2, MD_REG1_32BIT |
MD_REG2_32BIT);
md_ucmp_reg_reg_word_32(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_PCMP:
{
/* Compare native word values with -1, 0, or 1 result */
UNROLL_START();
GetTopTwoWordRegisters(&unroll, ®, ®2,
MD_REG1_NATIVE |
MD_REG2_NATIVE);
md_ucmp_reg_reg_word_native(unroll.out, reg, reg2);
FreeTopRegister(&unroll, -1);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETEQ:
{
/* Set if top of stack is equal to zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_seteq_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETNE:
{
/* Set if top of stack is not equal to zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_setne_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETLT:
{
/* Set if top of stack is less than zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_setlt_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETLE:
{
/* Set if top of stack is less than or equal to zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_setle_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETGT:
{
/* Set if top of stack is greater than zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_setgt_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
case 0x100 + COP_PREFIX_SETGE:
{
/* Set if top of stack is greater than or equal to zero */
UNROLL_START();
reg = GetTopWordRegister(&unroll, MD_REG1_32BIT);
md_setge_reg(unroll.out, reg);
MODIFY_UNROLL_PC(CVMP_LEN_NONE);
}
break;
#endif /* IL_UNROLL_CASES */
Index: md_arm.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_arm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_arm.h 14 May 2003 06:17:12 -0000 1.1
--- md_arm.h 10 Jul 2003 07:28:17 -0000 1.2
***************
*** 388,529 ****
/*
! * Helper routine for the complex cases of "arm_mov_reg_imm".
! * TODO: make this static.
*/
! arm_inst_ptr _arm_mov_reg_imm(arm_inst_ptr inst, int reg, int value)
! {
! /* Handle bytes in various positions */
! if((value & 0x000000FF) == value)
! {
! arm_mov_reg_imm8(inst, reg, value);
! return inst;
! }
! else if((value & 0x0000FF00) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
! return inst;
! }
! else if((value & 0x00FF0000) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
! return inst;
! }
! else if((value & 0xFF000000) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
! return inst;
! }
!
! /* Handle inverted bytes in various positions */
! value = ~value;
! if((value & 0x000000FF) == value)
! {
! arm_mov_reg_imm8(inst, reg, value);
! arm_alu_reg(inst, ARM_MVN, reg, reg);
! return inst;
! }
! else if((value & 0x0000FF00) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, (value >> 8), 12);
! arm_alu_reg(inst, ARM_MVN, reg, reg);
! return inst;
! }
! else if((value & 0x00FF0000) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, (value >> 16), 8);
! arm_alu_reg(inst, ARM_MVN, reg, reg);
! return inst;
! }
! else if((value & 0xFF000000) == value)
! {
! arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
! arm_alu_reg(inst, ARM_MVN, reg, reg);
! return inst;
! }
!
! /* Build the value the hard way, byte by byte */
! value = ~value;
! if((value & 0xFF000000) != 0)
! {
! arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
! if((value & 0x00FF0000) != 0)
! {
! arm_alu_reg_imm8_rotate
! (inst, ARM_ADD, reg, reg, ((value >> 16) &
0xFF), 8);
! }
! if((value & 0x0000FF00) != 0)
! {
! arm_alu_reg_imm8_rotate
! (inst, ARM_ADD, reg, reg, ((value >> 8) &
0xFF), 12);
! }
! if((value & 0x000000FF) != 0)
! {
! arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
! }
! }
! else if((value & 0x00FF0000) != 0)
! {
! arm_mov_reg_imm8_rotate(inst, reg, ((value >> 16) & 0xFF), 8);
! if((value & 0x0000FF00) != 0)
! {
! arm_alu_reg_imm8_rotate
! (inst, ARM_ADD, reg, reg, ((value >> 8) &
0xFF), 12);
! }
! if((value & 0x000000FF) != 0)
! {
! arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
! }
! }
! else if((value & 0x0000FF00) != 0)
! {
! arm_mov_reg_imm8_rotate(inst, reg, ((value >> 8) & 0xFF), 12);
! if((value & 0x000000FF) != 0)
! {
! arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value &
0xFF));
! }
! }
! else
! {
! arm_mov_reg_imm8(inst, reg, (value & 0xFF));
! }
! return inst;
! }
/*
! * Helper routine for the complex cases of "arm_alu_reg_imm".
*/
! arm_inst_ptr _arm_alu_reg_imm(arm_inst_ptr inst, int opc,
! int dreg, int sreg, int imm,
! int saveWork)
! {
! int tempreg;
! if(saveWork)
! {
! if(dreg != ARM_R2 && sreg != ARM_R2)
! {
! tempreg = ARM_R2;
! }
! else if(dreg != ARM_R3 && sreg != ARM_R3)
! {
! tempreg = ARM_R3;
! }
! else
! {
! tempreg = ARM_R4;
! }
! arm_push_reg(inst, tempreg);
! }
! else
! {
! tempreg = ARM_WORK;
! }
! _arm_mov_reg_imm(inst, tempreg, imm);
! arm_alu_reg_reg(inst, opc, dreg, sreg, tempreg);
! if(saveWork)
! {
! arm_pop_reg(inst, tempreg);
! }
! return inst;
! }
#ifdef __cplusplus
--- 388,434 ----
/*
! * Set a register to a 0 or 1 value based on a condition.
*/
! extern md_inst_ptr _md_arm_setcc(md_inst_ptr inst, int reg,
! int cond, int
invcond);
! #define md_seteq_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_EQ, ARM_CC_NE);
} while (0)
! #define md_setne_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_NE, ARM_CC_EQ);
} while (0)
! #define md_setlt_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_LT, ARM_CC_GE);
} while (0)
! #define md_setle_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_LE, ARM_CC_GT);
} while (0)
! #define md_setgt_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_GT, ARM_CC_LE);
} while (0)
! #define md_setge_reg(inst,reg) \
! do { (inst) = _md_arm_setcc \
! ((inst), (reg), ARM_CC_GE, ARM_CC_LT);
} while (0)
/*
! * Set a register to -1, 0, or 1 based on comparing two values.
*/
! #define md_cmp_reg_reg_word_32(inst,reg1,reg2) \
! do { \
! arm_test_reg_reg((inst), ARM_CMP, reg1, reg2); \
! arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0,
1, ARM_CC_GT); \
! arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0,
0, ARM_CC_LE); \
! arm_alu_reg_cond((inst), ARM_MVN, reg1, reg1,
ARM_CC_LT); \
! } while (0)
! #define md_ucmp_reg_reg_word_32(inst,reg1,reg2) \
! do { \
! arm_test_reg_reg((inst), ARM_CMP, reg1, reg2); \
! arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0,
1, \
!
ARM_CC_GT_UN); \
! arm_alu_reg_imm8_cond((inst), ARM_MOV, reg1, 0,
0, \
!
ARM_CC_LE_UN); \
! arm_alu_reg_cond((inst), ARM_MVN, reg1, reg1, \
! ARM_CC_LT_UN);
\
! } while (0)
#ifdef __cplusplus
Index: md_default.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_default.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_default.h 14 May 2003 06:17:12 -0000 1.1
--- md_default.h 10 Jul 2003 07:28:17 -0000 1.2
***************
*** 75,82 ****
#define md_div_reg_reg_float(inst,reg1,reg2) \
do { ; } while (0)
! #define md_rem_reg_reg_float(inst,reg1,reg2) \
do { ; } while (0)
#define md_neg_reg_float(inst,reg) \
do { ; } while (0)
#endif
--- 75,92 ----
#define md_div_reg_reg_float(inst,reg1,reg2) \
do { ; } while (0)
! #define md_rem_reg_reg_float(inst,reg1,reg2,used) \
do { ; } while (0)
#define md_neg_reg_float(inst,reg) \
do { ; } while (0)
+ #endif
+
+ /*
+ * Set a register to -1, 0, or 1 based on comparing two values.
+ */
+ #if defined(IL_NATIVE_INT32) && !defined(md_cmp_reg_reg_word_native)
+ #define md_cmp_reg_reg_word_native(inst,reg1,reg2) \
+ md_cmp_reg_reg_word_32((inst), (reg1), (reg2))
+ #define md_ucmp_reg_reg_word_native(inst,reg1,reg2) \
+ md_ucmp_reg_reg_word_32((inst), (reg1), (reg2))
#endif
Index: md_x86.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/md_x86.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** md_x86.h 14 May 2003 06:17:12 -0000 1.1
--- md_x86.h 10 Jul 2003 07:28:17 -0000 1.2
***************
*** 132,136 ****
* inline using a simple opcode.
*/
! #define MD_HAS_INT_DIVISION 0
/*
--- 132,136 ----
* inline using a simple opcode.
*/
! #define MD_HAS_INT_DIVISION 1
/*
***************
*** 232,262 ****
* Store a byte value to an offset from a pointer register.
*/
! static md_inst_ptr _x86_mov_membase_reg_byte
! (md_inst_ptr inst, int basereg, int offset, int srcreg)
! {
! if(srcreg == X86_EAX || srcreg == X86_EBX ||
! srcreg == X86_ECX || srcreg == X86_EDX)
! {
! x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
! }
! else if(basereg != X86_EAX)
! {
! x86_push_reg(inst, X86_EAX);
! x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
! x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
! x86_pop_reg(inst, X86_EAX);
! }
! else
! {
! x86_push_reg(inst, X86_EDX);
! x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
! x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
! x86_pop_reg(inst, X86_EDX);
! }
! return inst;
! }
#define md_store_membase_byte(inst,reg,basereg,offset) \
do { \
! (inst) = _x86_mov_membase_reg_byte \
((inst), (basereg), (int)(offset),
(reg)); \
} while (0)
--- 232,240 ----
* Store a byte value to an offset from a pointer register.
*/
! md_inst_ptr _md_x86_mov_membase_reg_byte
! (md_inst_ptr inst, int basereg, int offset, int srcreg);
#define md_store_membase_byte(inst,reg,basereg,offset) \
do { \
! (inst) = _md_x86_mov_membase_reg_byte \
((inst), (basereg), (int)(offset),
(reg)); \
} while (0)
***************
*** 308,312 ****
* Perform arithmetic and logical operations on 32-bit word registers.
*
! * Note: x86 divisions and shifts are handled elsewhere, because they are
hard.
*/
#define md_add_reg_reg_word_32(inst,reg1,reg2) \
--- 286,290 ----
* Perform arithmetic and logical operations on 32-bit word registers.
*
! * Division is tricky, so it is handled elsewhere for x86.
*/
#define md_add_reg_reg_word_32(inst,reg1,reg2) \
***************
*** 316,319 ****
--- 294,299 ----
#define md_mul_reg_reg_word_32(inst,reg1,reg2) \
x86_imul_reg_reg((inst), (reg1), (reg2))
+ extern md_inst_ptr _md_x86_divide(md_inst_ptr inst, int reg1, int reg2,
+ int isSigned,
int wantRemainder);
#define md_div_reg_reg_word_32(inst,reg1,reg2) \
do { ; } while (0)
***************
*** 334,343 ****
#define md_not_reg_word_32(inst,reg) \
x86_not_reg((inst), (reg))
#define md_shl_reg_reg_word_32(inst,reg1,reg2) \
! do { ; } while (0)
#define md_shr_reg_reg_word_32(inst,reg1,reg2) \
! do { ; } while (0)
#define md_ushr_reg_reg_word_32(inst,reg1,reg2) \
! do { ; } while (0)
/*
--- 314,327 ----
#define md_not_reg_word_32(inst,reg) \
x86_not_reg((inst), (reg))
+ extern md_inst_ptr _md_x86_shift(md_inst_ptr inst, int opc, int reg1, int
reg2);
#define md_shl_reg_reg_word_32(inst,reg1,reg2) \
! do { (inst) = _md_x86_shift \
! ((inst), X86_SHL, (reg1), (reg2)); }
while (0)
#define md_shr_reg_reg_word_32(inst,reg1,reg2) \
! do { (inst) = _md_x86_shift \
! ((inst), X86_SAR, (reg1), (reg2)); }
while (0)
#define md_ushr_reg_reg_word_32(inst,reg1,reg2) \
! do { (inst) = _md_x86_shift \
! ((inst), X86_SHR, (reg1), (reg2)); }
while (0)
/*
***************
*** 355,360 ****
#define md_div_reg_reg_float(inst,reg1,reg2) \
x86_fp_op_reg((inst), X86_FDIV, 1, 1)
! #define md_rem_reg_reg_float(inst,reg1,reg2) \
! do { ; } while (0)
#define md_neg_reg_float(inst,reg) \
x86_fchs((inst))
--- 339,347 ----
#define md_div_reg_reg_float(inst,reg1,reg2) \
x86_fp_op_reg((inst), X86_FDIV, 1, 1)
! extern md_inst_ptr _md_x86_rem_float
! (md_inst_ptr inst, int reg1, int reg2, int used);
! #define md_rem_reg_reg_float(inst,reg1,reg2,used) \
! do { (inst) = _md_x86_rem_float \
! ((inst), (reg1), (reg2), (used)); }
while (0)
#define md_neg_reg_float(inst,reg) \
x86_fchs((inst))
***************
*** 447,450 ****
--- 434,466 ----
#define md_mov_reg_reg(inst,dreg,sreg) \
x86_mov_reg_reg((inst), (dreg), (sreg), 4)
+
+ /*
+ * Set a register to a 0 or 1 value based on a condition.
+ */
+ extern md_inst_ptr _md_x86_setcc(md_inst_ptr inst, int reg, int cond);
+ #define md_seteq_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_EQ);
} while (0)
+ #define md_setne_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_NE);
} while (0)
+ #define md_setlt_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_LT);
} while (0)
+ #define md_setle_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_LE);
} while (0)
+ #define md_setgt_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_GT);
} while (0)
+ #define md_setge_reg(inst,reg) \
+ do { (inst) = _md_x86_setcc((inst), (reg), X86_CC_GE);
} while (0)
+
+ /*
+ * Set a register to -1, 0, or 1 based on comparing two values.
+ */
+ extern md_inst_ptr _md_x86_compare
+ (md_inst_ptr inst, int reg1, int reg2, int
isSigned);
+ #define md_cmp_reg_reg_word_32(inst,reg1,reg2) \
+ do { (inst) = _md_x86_compare \
+ ((inst), (reg1), (reg2), 1); } while (0)
+ #define md_ucmp_reg_reg_word_32(inst,reg1,reg2) \
+ do { (inst) = _md_x86_compare \
+ ((inst), (reg1), (reg2), 0); } while (0)
#ifdef __cplusplus
Index: unroll.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/unroll.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** unroll.c 14 May 2003 06:17:12 -0000 1.1
--- unroll.c 10 Jul 2003 07:28:17 -0000 1.2
***************
*** 1278,1282 ****
*/
#define IL_UNROLL_GLOBAL
! //#include "unroll_arith.c"
//#include "unroll_branch.c"
//#include "unroll_const.c"
--- 1278,1282 ----
*/
#define IL_UNROLL_GLOBAL
! #include "unroll_arith.c"
//#include "unroll_branch.c"
//#include "unroll_const.c"
***************
*** 1360,1364 ****
{
#define IL_UNROLL_CASES
! //#include "unroll_arith.c"
//#include "unroll_branch.c"
//#include "unroll_const.c"
--- 1360,1364 ----
{
#define IL_UNROLL_CASES
! #include "unroll_arith.c"
//#include "unroll_branch.c"
//#include "unroll_const.c"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/engine md_arm.c, NONE, 1.1 md_x86.c, NONE, 1.1 unroll_arith.c, NONE, 1.1 md_arm.h, 1.1, 1.2 md_default.h, 1.1, 1.2 md_x86.h, 1.1, 1.2 unroll.c, 1.1, 1.2,
Rhys Weatherley <address@hidden> <=