From d535be87b1014d1a444b7c08f2a44b2d98aa2454 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 22 Oct 2016 00:02:15 +0200 Subject: [PATCH] fef4 and fef8 is now cleaner, albeit slower; add some more register alias stuff. --- mach/powerpc/mcg/platform.c | 5 +++++ mach/powerpc/mcg/table | 6 ++++++ mach/proto/mcg/hop.c | 22 ++++++++++++++++--- mach/proto/mcg/treebuilder.c | 41 ++++++++++-------------------------- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/mach/powerpc/mcg/platform.c b/mach/powerpc/mcg/platform.c index e3ab26913..e0a7c1a2c 100644 --- a/mach/powerpc/mcg/platform.c +++ b/mach/powerpc/mcg/platform.c @@ -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); diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index 236f5c7c1..f1bc27a47 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -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" diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index 9dbb010cc..32bd44d3b 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -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; } diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 7b9ba842c..180f41000 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -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; }