diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index 448e1123e..79e2f355c 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -177,6 +177,11 @@ PATTERNS emit "addi sp, sp, 4" cost 8; + out:(long)reg = POP.D + emit "lfd %out, 0(sp)" + emit "addi sp, sp, 8" + cost 8; + SETRET.I(in:(ret)reg) emit "! setret4" cost 1; @@ -231,6 +236,13 @@ PATTERNS emit "addi sp, sp, 8" cost 16; + out:(long)reg = COPYD.L(in:(double)reg) + emit "sfdu %in, -8(sp)" + emit "lwz %out.0, 4(sp)" + emit "lwz %out.1, 0(sp)" + emit "addi sp, sp, 8" + cost 16; + /* Memory operations */ @@ -362,6 +374,11 @@ PATTERNS emit "bl .fromd2i" cost 4; + out:(long)reg = FROMF.L(in:(double)reg) + with corrupted(volatile) + emit "bl .fromf2l" + cost 4; + #if 0 /* byte conversions */ @@ -534,6 +551,19 @@ PATTERNS emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */ cost 8; + out:(int)reg = IFLT.I(in:(cr)cr) + emit "mfcr %out" /* get cr0 */ + emit "andi. %out, %out, 1" /* leave just LT */ + cost 8; + + out:(int)reg = IFLE.I(in:(cr)cr) + emit "mfcr %out" /* get cr0 */ + emit "andi. %out, %out, 5" /* leave just LT and EQ */ + emit "cntlzw %out, %out" /* returns 0..32 */ + emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */ + emit "xori %out, %out, 1" /* negate */ + cost 8; + /* Conversions */ diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index b64ff83ce..66a69edef 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -361,6 +361,7 @@ static void insn_simple(int opcode) case op_cii: simple_convert(IR_FROMSI); break; case op_ciu: simple_convert(IR_FROMSI); break; case op_cui: simple_convert(IR_FROMUI); break; + case op_cfu: simple_convert(IR_FROMF); break; /* FIXME: technically wrong */ case op_cfi: simple_convert(IR_FROMF); break; case op_cif: simple_convert(IR_FROMSI); break; case op_cff: simple_convert(IR_FROMF); break; @@ -1058,12 +1059,12 @@ static void insn_ivalue(int opcode, arith value) } materialise_stack(); - push( - appendir( - new_ir1( - IR_CALL, EM_wordsize, - new_labelir(helper) - ) + /* No push here, because the helper function leaves the result on + * the physical stack (which is very dubious). */ + appendir( + new_ir1( + IR_CALL, EM_wordsize, + new_labelir(helper) ) ); break; @@ -1304,6 +1305,19 @@ static void insn_ivalue(int opcode, arith value) break; } + /* FIXME: These instructions are really complex and barely used + * (Modula-2 bitset support, I believe). Leave them until leter. */ + case op_inn: + { + appendir( + new_ir1( + IR_CALL, 0, + new_labelir(".unimplemented") + ) + ); + break; + } + case op_lin: { /* Set line number --- ignore. */