Update the table to return call output values in the right registers. Fix the
register allocator so the corrupted registers only apply to throughs (otherwise, you can't put output registers in corrupted registers).
This commit is contained in:
parent
b5c1d622f5
commit
852d3a691d
|
@ -19,7 +19,7 @@ REGISTERS
|
||||||
r6 int volatile;
|
r6 int volatile;
|
||||||
r5 int volatile;
|
r5 int volatile;
|
||||||
r4 int volatile;
|
r4 int volatile;
|
||||||
r3 int volatile ret;
|
r3 int volatile iret;
|
||||||
|
|
||||||
r31 int;
|
r31 int;
|
||||||
r30 int;
|
r30 int;
|
||||||
|
@ -185,7 +185,7 @@ PATTERNS
|
||||||
emit "addi sp, sp, 8"
|
emit "addi sp, sp, 8"
|
||||||
cost 8;
|
cost 8;
|
||||||
|
|
||||||
SETRET.I(in:(ret)reg)
|
SETRET.I(in:(iret)reg)
|
||||||
emit "! setret4"
|
emit "! setret4"
|
||||||
cost 1;
|
cost 1;
|
||||||
|
|
||||||
|
@ -392,12 +392,12 @@ PATTERNS
|
||||||
emit "li32 %out.1, 0"
|
emit "li32 %out.1, 0"
|
||||||
cost 8;
|
cost 8;
|
||||||
|
|
||||||
out:(ret)reg = FROMF.I(in:(dret)reg)
|
out:(iret)reg = FROMF.I(in:(dret)reg)
|
||||||
with corrupted(volatile)
|
with corrupted(volatile)
|
||||||
emit "bl .fromf2i"
|
emit "bl .fromf2i"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
out:(ret)reg = FROMD.I(in:(dret)reg)
|
out:(iret)reg = FROMD.I(in:(dret)reg)
|
||||||
with corrupted(volatile)
|
with corrupted(volatile)
|
||||||
emit "bl .fromd2i"
|
emit "bl .fromd2i"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
@ -407,17 +407,17 @@ PATTERNS
|
||||||
emit "bl .fromf2l"
|
emit "bl .fromf2l"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
out:(dret)reg = FROMSI.D(in:(ret)reg)
|
out:(dret)reg = FROMSI.D(in:(iret)reg)
|
||||||
with corrupted(volatile)
|
with corrupted(volatile)
|
||||||
emit "bl .fromsi2d"
|
emit "bl .fromsi2d"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
out:(fret)reg = FROMUI.F(in:(ret)reg)
|
out:(fret)reg = FROMUI.F(in:(iret)reg)
|
||||||
with corrupted(volatile)
|
with corrupted(volatile)
|
||||||
emit "bl .fromui2f"
|
emit "bl .fromui2f"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
out:(dret)reg = FROMUI.D(in:(ret)reg)
|
out:(dret)reg = FROMUI.D(in:(iret)reg)
|
||||||
with corrupted(volatile)
|
with corrupted(volatile)
|
||||||
emit "bl .fromui2d"
|
emit "bl .fromui2d"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
@ -493,8 +493,8 @@ PATTERNS
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
CALLLABEL(CALL)
|
CALLLABEL(CALL)
|
||||||
out:(int)reg = CALLLABEL(CALL.I)
|
out:(iret)reg = CALLLABEL(CALL.I)
|
||||||
out:(long)reg = CALLLABEL(CALL.L)
|
out:(lret)reg = CALLLABEL(CALL.L)
|
||||||
|
|
||||||
#define CALLINDIRECT(insn) \
|
#define CALLINDIRECT(insn) \
|
||||||
insn (dest:(int)reg) \
|
insn (dest:(int)reg) \
|
||||||
|
@ -504,8 +504,8 @@ PATTERNS
|
||||||
cost 8;
|
cost 8;
|
||||||
|
|
||||||
CALLINDIRECT(CALL)
|
CALLINDIRECT(CALL)
|
||||||
out:(int)reg = CALLINDIRECT(CALL.I)
|
out:(iret)reg = CALLINDIRECT(CALL.I)
|
||||||
out:(long)reg = CALLINDIRECT(CALL.L)
|
out:(lret)reg = CALLINDIRECT(CALL.L)
|
||||||
|
|
||||||
JUMP(dest:LABEL.I)
|
JUMP(dest:LABEL.I)
|
||||||
emit "b $dest"
|
emit "b $dest"
|
||||||
|
|
|
@ -153,8 +153,7 @@ static bool allocatable_stackable_input(struct hreg* hreg, struct vreg* vreg)
|
||||||
static bool allocatable_stackable_output(struct hreg* hreg, struct vreg* vreg)
|
static bool allocatable_stackable_output(struct hreg* hreg, struct vreg* vreg)
|
||||||
{
|
{
|
||||||
return !register_used(current_outs, hreg) &&
|
return !register_used(current_outs, hreg) &&
|
||||||
(hreg->attrs & vreg->type) &&
|
(hreg->attrs & vreg->type);
|
||||||
!(hreg->attrs & current_hop->insndata->corrupts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool allocatable_input(struct hreg* hreg, struct vreg* vreg)
|
static bool allocatable_input(struct hreg* hreg, struct vreg* vreg)
|
||||||
|
@ -174,7 +173,8 @@ static bool allocatable_output(struct hreg* hreg, struct vreg* vreg)
|
||||||
static bool allocatable_through(struct hreg* hreg, struct vreg* vreg)
|
static bool allocatable_through(struct hreg* hreg, struct vreg* vreg)
|
||||||
{
|
{
|
||||||
return allocatable_stackable_input(hreg, vreg) &&
|
return allocatable_stackable_input(hreg, vreg) &&
|
||||||
allocatable_stackable_output(hreg, vreg);
|
allocatable_stackable_output(hreg, vreg) &&
|
||||||
|
!(hreg->attrs & current_hop->insndata->corrupts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hreg* find_input_reg(struct vreg* vreg)
|
static struct hreg* find_input_reg(struct vreg* vreg)
|
||||||
|
@ -203,9 +203,7 @@ static struct hreg* find_output_reg(struct vreg* vreg)
|
||||||
{
|
{
|
||||||
hreg = hregs.item[i];
|
hreg = hregs.item[i];
|
||||||
if (allocatable_output(hreg, vreg))
|
if (allocatable_output(hreg, vreg))
|
||||||
{
|
|
||||||
return hreg;
|
return hreg;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue