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); hop_add_insel(hop, "mr %H, %H", dest, src);
break; 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_float_ATTR:
case burm_double_ATTR: case burm_double_ATTR:
hop_add_insel(hop, "fmr %H, %H", dest, src); hop_add_insel(hop, "fmr %H, %H", dest, src);

View file

@ -162,6 +162,12 @@ PATTERNS
emit "addi sp, sp, 4" emit "addi sp, sp, 4"
cost 8; 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 out:(float)reg = POPF4
emit "lfs %out, 0(sp)" emit "lfs %out, 0(sp)"
emit "addi sp, sp, 4" emit "addi sp, sp, 4"

View file

@ -90,9 +90,25 @@ void hop_add_insel(struct hop* hop, const char* fmt, ...)
{ {
if (*fmt == '%') if (*fmt == '%')
{ {
int index = 0;
fmt += 2; fmt += 2;
again:
switch (fmt[-1]) 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': case 'd':
hop_add_string_insel(hop, aprintf("%d", va_arg(ap, int))); hop_add_string_insel(hop, aprintf("%d", va_arg(ap, int)));
break; break;
@ -110,11 +126,11 @@ void hop_add_insel(struct hop* hop, const char* fmt, ...)
break; break;
case 'H': 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; break;
case 'V': 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; break;
} }
} }
@ -220,7 +236,7 @@ char* hop_render(struct hop* hop)
if (hreg) if (hreg)
appendf("%s", hreg->brd->names[insel->index]); appendf("%s", hreg->brd->names[insel->index]);
else else
appendf("%%%d", vreg->id); appendf("%%%d.%d", vreg->id, insel->index);
break; break;
} }

View file

@ -516,7 +516,7 @@ static void insn_ivalue(int opcode, arith value)
new_ir1( new_ir1(
IR_LOAD, EM_wordsize, IR_LOAD, EM_wordsize,
new_ir1( new_ir1(
IR_LOAD, EM_wordsize, IR_LOAD, EM_pointersize,
new_localir(value) new_localir(value)
) )
) )
@ -528,7 +528,7 @@ static void insn_ivalue(int opcode, arith value)
new_ir2( new_ir2(
IR_STORE, EM_wordsize, IR_STORE, EM_wordsize,
new_ir1( new_ir1(
IR_LOAD, EM_wordsize, IR_LOAD, EM_pointersize,
new_localir(value) new_localir(value)
), ),
pop(EM_wordsize) pop(EM_wordsize)
@ -912,41 +912,22 @@ static void insn_ivalue(int opcode, arith value)
{ {
struct ir* e; struct ir* e;
struct ir* f = pop(value); struct ir* f = pop(value);
/* fef is implemented by synthesising a call to frexp. */ /* fef is implemented by calling a helper function which then mutates
push( * the stack. We read the return values off the stack when retracting
new_labelir(".fef_exp") * the stack pointer. */
);
push( push(f);
f push(new_wordir(0));
);
materialise_stack(); materialise_stack();
appendir( appendir(
new_ir1( new_ir1(
IR_CALL, 0, 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; break;
} }