+2007-01-02 Aleksey Demakov <ademakov@gmail.com>
+
+ * jit/jit-rules-x86.ins: add JIT_OP_IMIN_UN rule (based on the
+ patch #5540 by Kirill Kononenko).
+
+ * jit/jit-reg-alloc.c (set_regdesc_value, set_regdesc_register)
+ (choose_output_register): handle EARLY_CLOBBER flag for dest value.
+
2006-12-30 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-reg-class.c, jit/jit-reg-class.h, jit/Makefile.am: add
desc = ®s->descs[index];
desc->value = value;
- if(index > 0 || regs->ternary)
- {
- if((flags & _JIT_REGS_EARLY_CLOBBER) != 0)
- {
- desc->clobber = 1;
- desc->early_clobber = 1;
- }
- else if((flags & _JIT_REGS_CLOBBER) != 0)
- {
- desc->clobber = 1;
- }
- }
+ desc->clobber = ((flags & (_JIT_REGS_CLOBBER | _JIT_REGS_EARLY_CLOBBER)) != 0);
+ desc->early_clobber = ((flags & _JIT_REGS_EARLY_CLOBBER) != 0);
desc->regclass = regclass;
desc->live = live;
desc->used = used;
static void
set_regdesc_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, int other_reg)
{
- int is_output;
-
+ int assign;
if(reg >= 0)
{
- is_output = (index == 0 && !regs->ternary);
+ assign = (index > 0 || regs->ternary || regs->descs[0].early_clobber);
regs->descs[index].reg = reg;
regs->descs[index].other_reg = other_reg;
jit_reg_set_used(gen->touched, reg);
- if(!is_output)
+ if(assign)
{
jit_reg_set_used(regs->assigned, reg);
}
if(other_reg >= 0)
{
jit_reg_set_used(gen->touched, other_reg);
- if(!is_output)
+ if(assign)
{
jit_reg_set_used(regs->assigned, other_reg);
}
}
if(regs->free_dest)
{
+ if(regs->descs[0].early_clobber
+ && regs->descs[0].value->in_global_register)
+ {
+ if(regs->descs[0].value == regs->descs[1].value)
+ {
+ continue;
+ }
+ if(regs->descs[0].value == regs->descs[2].value)
+ {
+ continue;
+ }
+ }
use_cost = 0;
}
else if(regs->descs[0].value->in_global_register)
}
if(regs->free_dest)
{
+ if(regs->descs[0].early_clobber)
+ {
+ if(regs->descs[1].value
+ && regs->descs[1].value->in_register
+ && regs->descs[1].value->reg == reg)
+ {
+ continue;
+ }
+ if(regs->descs[2].value
+ && regs->descs[2].value->in_register
+ && regs->descs[2].value->reg == reg)
+ {
+ continue;
+ }
+ }
use_cost = 0;
}
else if(regs->descs[1].value
{
continue;
}
-#if !ALLOW_CLOBBER_GLOBAL
if(other_reg >= 0 && jit_reg_is_used(gen->permanent, other_reg))
{
+#if ALLOW_CLOBBER_GLOBAL
+ use_cost += COST_CLOBBER_GLOBAL;
+#else
continue;
- }
#endif
+ }
if(jit_reg_is_used(regs->clobber, reg)
|| (other_reg >= 0 && jit_reg_is_used(regs->clobber, other_reg)))
{
{
use_cost += compute_spill_cost(gen, regs, reg, other_reg);
}
-#if ALLOW_CLOBBER_GLOBAL
- if(other_reg >= 0 && jit_reg_is_used(gen->permanent, other_reg))
- {
- use_cost += COST_CLOBBER_GLOBAL;
- }
-#endif
}
if(use_cost < suitable_cost
x86_fabs(inst);
}
+JIT_OP_IMIN_UN:
+ [=+reg, +reg, reg] -> {
+ x86_alu_reg_reg(inst, X86_SUB, $2, $3);
+ x86_alu_reg_reg(inst, X86_SBB, $1, $1);
+ x86_alu_reg_reg(inst, X86_AND, $1, $2);
+ x86_alu_reg_reg(inst, X86_ADD, $1, $3);
+ }
+
JIT_OP_ISIGN:
[=reg, imm] -> {
if($2 < 0)