fef4 and fef8 is now cleaner, albeit slower; add some more register alias

stuff.
This commit is contained in:
David Given 2016-10-22 00:02:15 +02:00
parent 4db402f229
commit d535be87b1
4 changed files with 41 additions and 33 deletions

View file

@ -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);

View file

@ -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"

View file

@ -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;
}

View file

@ -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;
}