fef4 and fef8 is now cleaner, albeit slower; add some more register alias
stuff.
This commit is contained in:
parent
4db402f229
commit
d535be87b1
|
@ -202,6 +202,11 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
|
|||
hop_add_insel(hop, "mr %H, %H", dest, src);
|
||||
break;
|
||||
|
||||
case burm_pair_ATTR:
|
||||
hop_add_insel(hop, "mr %0H, %0H", dest, src);
|
||||
hop_add_insel(hop, "mr %1H, %1H", dest, src);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "fmr %H, %H", dest, src);
|
||||
|
|
|
@ -162,6 +162,12 @@ PATTERNS
|
|||
emit "addi sp, sp, 4"
|
||||
cost 8;
|
||||
|
||||
out:(pair)reg = POP8
|
||||
emit "lwz %out.0, 4(sp)"
|
||||
emit "lwz %out.1, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 12;
|
||||
|
||||
out:(float)reg = POPF4
|
||||
emit "lfs %out, 0(sp)"
|
||||
emit "addi sp, sp, 4"
|
||||
|
|
|
@ -90,9 +90,25 @@ void hop_add_insel(struct hop* hop, const char* fmt, ...)
|
|||
{
|
||||
if (*fmt == '%')
|
||||
{
|
||||
int index = 0;
|
||||
fmt += 2;
|
||||
again:
|
||||
switch (fmt[-1])
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
index = fmt[-1] - '0';
|
||||
fmt++;
|
||||
goto again;
|
||||
|
||||
case 'd':
|
||||
hop_add_string_insel(hop, aprintf("%d", va_arg(ap, int)));
|
||||
break;
|
||||
|
@ -110,11 +126,11 @@ void hop_add_insel(struct hop* hop, const char* fmt, ...)
|
|||
break;
|
||||
|
||||
case 'H':
|
||||
hop_add_hreg_insel(hop, va_arg(ap, struct hreg*), 0);
|
||||
hop_add_hreg_insel(hop, va_arg(ap, struct hreg*), index);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
hop_add_vreg_insel(hop, va_arg(ap, struct vreg*), 0);
|
||||
hop_add_vreg_insel(hop, va_arg(ap, struct vreg*), index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +236,7 @@ char* hop_render(struct hop* hop)
|
|||
if (hreg)
|
||||
appendf("%s", hreg->brd->names[insel->index]);
|
||||
else
|
||||
appendf("%%%d", vreg->id);
|
||||
appendf("%%%d.%d", vreg->id, insel->index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ static void insn_ivalue(int opcode, arith value)
|
|||
new_ir1(
|
||||
IR_LOAD, EM_wordsize,
|
||||
new_ir1(
|
||||
IR_LOAD, EM_wordsize,
|
||||
IR_LOAD, EM_pointersize,
|
||||
new_localir(value)
|
||||
)
|
||||
)
|
||||
|
@ -528,7 +528,7 @@ static void insn_ivalue(int opcode, arith value)
|
|||
new_ir2(
|
||||
IR_STORE, EM_wordsize,
|
||||
new_ir1(
|
||||
IR_LOAD, EM_wordsize,
|
||||
IR_LOAD, EM_pointersize,
|
||||
new_localir(value)
|
||||
),
|
||||
pop(EM_wordsize)
|
||||
|
@ -912,41 +912,22 @@ static void insn_ivalue(int opcode, arith value)
|
|||
{
|
||||
struct ir* e;
|
||||
struct ir* f = pop(value);
|
||||
/* fef is implemented by synthesising a call to frexp. */
|
||||
push(
|
||||
new_labelir(".fef_exp")
|
||||
);
|
||||
push(
|
||||
f
|
||||
);
|
||||
/* fef is implemented by calling a helper function which then mutates
|
||||
* the stack. We read the return values off the stack when retracting
|
||||
* the stack pointer. */
|
||||
|
||||
push(f);
|
||||
push(new_wordir(0));
|
||||
|
||||
materialise_stack();
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_CALL, 0,
|
||||
new_labelir((value == 4) ? "frexpf" : "frexp")
|
||||
new_labelir((value == 4) ? ".fef4" : ".fef8")
|
||||
)
|
||||
);
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_STACKADJUST, EM_wordsize,
|
||||
new_wordir(4 + value)
|
||||
)
|
||||
);
|
||||
e = appendir(
|
||||
new_ir0(
|
||||
IR_GETRET, value
|
||||
)
|
||||
);
|
||||
push(
|
||||
new_ir1(
|
||||
IR_LOAD, EM_wordsize,
|
||||
new_labelir(".fef_exp")
|
||||
)
|
||||
);
|
||||
push(
|
||||
e
|
||||
);
|
||||
|
||||
/* exit, leaving an int and then a float (or double) on the stack. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue