hop_add_insel(hop, "stwu %H, -4(sp)", src);
break;
+ case burm_pair_ATTR:
+ hop_add_insel(hop, "stwu %0H, -4(sp)", src);
+ hop_add_insel(hop, "stwu %1H, -4(sp)", src);
+ break;
+
case burm_float_ATTR:
hop_add_insel(hop, "stfsu %H, -4(sp)", src);
break;
hop_add_insel(hop, "lwz %H, 0(sp)", dest);
break;
+ case burm_pair_ATTR:
+ hop_add_insel(hop, "lwz %0H, 4(sp)", dest);
+ hop_add_insel(hop, "lwz %1H, 0(sp)", dest);
+ break;
+
case burm_float_ATTR:
hop_add_insel(hop, "lfs %H, 0(sp)", dest);
break;
hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
break;
+ case burm_double_ATTR:
+ hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest);
+ break;
+
default:
assert(false);
}
hop_add_insel(hop, "lfs %H, %S(fp) ! %H", dest, src, src);
break;
+ case burm_double_ATTR:
+ hop_add_insel(hop, "lfd %H, %S(fp) ! %H", dest, src, src);
+ break;
+
default:
assert(false);
}
/* Comparisons */
- cr:(cr)cr = COMPARES4(left:(int)reg, right:(int)reg)
+ cr:(cr)cr = COMPARES44(left:(int)reg, right:(int)reg)
emit "cmp %cr, 0, %left, %right"
cost 4;
- cr:(cr)cr = COMPARES4(left:(int)reg, right:CONST4)
+ cr:(cr)cr = COMPARES44(left:(int)reg, right:CONST4)
when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right"
cost 4;
- cr:(cr)cr = COMPAREU4(left:(int)reg, right:(int)reg)
+ cr:(cr)cr = COMPAREU44(left:(int)reg, right:(int)reg)
emit "cmpl %cr, 0, %left, %right"
cost 4;
- cr:(cr)cr = COMPAREU4(left:(int)reg, right:CONST4)
+ cr:(cr)cr = COMPAREU44(left:(int)reg, right:CONST4)
when signed_constant(%right, 16)
emit "cmpli %cr, 0, %left, $right"
cost 4;
- cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:(int)reg), result:CONST4)
+ out:(cr)cr = COMPARES44(in:(cr)cr, result:CONST4)
when specific_constant(%result, 0)
- emit "cmp %cr, 0, %left, %right"
- cost 4;
-
- cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4)
- when specific_constant(%result, 0)
- when signed_constant(%right, 16)
- emit "cmpi %cr, 0, %left, $right"
- cost 4;
-
- cr:(cr)cr = COMPARES4(COMPAREU4(left:(int)reg, right:(int)reg), result:CONST4)
- when specific_constant(%result, 0)
- emit "cmpl %cr, 0, %left, %right"
+ with %out == %in
+ emit "! COMPARES(cr, 0)"
cost 4;
emit "fsubs %out, %left, %right"
cost 4;
+ out:(double)reg = SUBF8(left:(double)reg, right:(double)reg)
+ emit "fsub %out, %left, %right"
+ cost 4;
+
out:(float)reg = MULF4(left:(float)reg, right:(float)reg)
emit "fmuls %out, %left, %right"
cost 4;
+ out:(double)reg = MULF8(left:(double)reg, right:(double)reg)
+ emit "fmul %out, %left, %right"
+ cost 4;
+
out:(float)reg = NEGF4(left:(float)reg)
emit "fneg %out, %left"
cost 4;
- cr:(cr)cr = COMPAREF4(left:(float)reg, right:(float)reg)
+ out:(double)reg = NEGF8(left:(double)reg)
+ emit "fneg %out, %left"
+ cost 4;
+
+ cr:(cr)cr = COMPAREF44(left:(float)reg, right:(float)reg)
emit "fcmpu %cr, %left, %right"
cost 4;
- cr:(cr)cr = COMPARES4(COMPAREF4(left:(float)reg, right:(float)reg), result:CONST4)
- when specific_constant(%result, 0)
+ cr:(cr)cr = COMPAREF84(left:(double)reg, right:(double)reg)
emit "fcmpu %cr, %left, %right"
- cost 4;
+ cost 4;
out:(ret)reg = CFI44(val:(fret)reg)
with corrupted(volatile)
- emit "bl .cfi4"
+ emit "bl .cfi44"
cost 4;
out:(fret)reg = CIF44(val:(ret)reg)
with corrupted(volatile)
- emit "bl .cif4"
+ emit "bl .cif44"
+ cost 4;
+
+ out:(ret)reg = CFI84(val:(dret)reg)
+ with corrupted(volatile)
+ emit "bl .cfi84"
cost 4;
+ out:(dret)reg = CIF48(val:(ret)reg)
+ with corrupted(volatile)
+ emit "bl .cif48"
+ cost 4;
+
+ out:(float)reg = CFF84(val:(double)reg)
+ emit "frsp %out, %val"
+ cost 4;
+
+ out:(double)reg = CFF48(val:(float)reg)
+ emit "fmr %out, %val"
+ cost 1;
+
/* vim: set sw=4 ts=4 expandtab : */
case INSEL_HREG:
{
struct hreg* hreg = insel->u.hreg;
- appendf("%s", hreg->brd->names[insel->index]);
+ if (hreg->brd)
+ appendf("%s", hreg->brd->names[insel->index]);
+ else
+ appendf("%s.%d", hreg->id, insel->index);
break;
}
case IR_MULF:
case IR_DIVF:
case IR_NEGF:
+ case IR_COMPAREF1:
+ case IR_COMPAREF2:
+ case IR_COMPAREF4:
+ case IR_COMPAREF8:
+ case IR_CFF1:
+ case IR_CFF2:
+ case IR_CFF4:
+ case IR_CFF8:
if (ir->left)
promote(ir->left);
if (ir->right)
);
}
-static struct ir* tristate_compare(int size, int opcode)
+static struct ir* compare(struct ir* left, struct ir* right,
+ int size, int opcode)
{
- struct ir* right = pop(size);
- struct ir* left = pop(size);
+ switch (size)
+ {
+ case 1: opcode += 0; break;
+ case 2: opcode += 1; break;
+ case 4: opcode += 2; break;
+ case 8: opcode += 3; break;
+ default:
+ fatal("can't compare things of size %d", size);
+ }
return
new_ir2(
);
}
+static struct ir* tristate_compare(int size, int opcode)
+{
+ struct ir* right = pop(size);
+ struct ir* left = pop(size);
+
+ return compare(left, right, size, opcode);
+}
+
static void simple_convert(int opcode)
{
struct ir* destsize = pop(EM_wordsize);
case op_cui: simple_convert(IR_CUI1); break;
case op_cfi: simple_convert(IR_CFI1); break;
case op_cif: simple_convert(IR_CIF1); break;
+ case op_cff: simple_convert(IR_CFF1); break;
case op_cmp:
push(
- tristate_compare(EM_pointersize, IR_COMPAREU)
+ tristate_compare(EM_pointersize, IR_COMPAREU1)
);
break;
break;
}
+ case op_trp:
+ {
+ materialise_stack();
+ appendir(
+ new_ir1(
+ IR_CALL, 0,
+ new_labelir(".trp")
+ )
+ );
+ }
+
case op_lni:
{
/* Increment line number --- ignore. */
appendir(
new_ir2(
irop, 0,
- new_ir2(
- IR_COMPARES, size,
- left, right
- ),
+ compare(left, right, size, IR_COMPARES1),
new_ir2(
IR_PAIR, 0,
new_bbir(truebb),
case op_ngf: simple_alu1(opcode, value, IR_NEGF); break;
case op_cmu: /* fall through */
- case op_cms: push(tristate_compare(value, IR_COMPAREU)); break;
- case op_cmi: push(tristate_compare(value, IR_COMPARES)); break;
- case op_cmf: push(tristate_compare(value, IR_COMPAREF)); break;
+ case op_cms: push(tristate_compare(value, IR_COMPAREU1)); break;
+ case op_cmi: push(tristate_compare(value, IR_COMPARES1)); break;
+ case op_cmf: push(tristate_compare(value, IR_COMPAREF1)); break;
case op_lol:
push(
case op_fef:
{
- struct ir* e;
struct ir* f = pop(value);
+
/* 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. */
break;
}
+ case op_fif:
+ {
+ /* fif 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. */
+
+ /* We start with two floats on the stack. */
+
+ materialise_stack();
+ appendir(
+ new_ir1(
+ IR_CALL, 0,
+ new_labelir((value == 4) ? ".fif4" : ".fif8")
+ )
+ );
+
+ /* exit, leaving two floats (or doubles) on the stack. */
+ break;
+ }
+
case op_lin:
{
/* Set line number --- ignore. */
S CIF4
S CIF8
+S CFF1
+S CFF2
+S CFF4
+S CFF8
+
# Tristate comparisons
-S COMPARES
-S COMPAREU
-S COMPAREF
+S COMPARES1
+S COMPARES2
+S COMPARES4
+S COMPARES8
+
+S COMPAREU1
+S COMPAREU2
+S COMPAREU4
+S COMPAREU8
+
+S COMPAREF1
+S COMPAREF2
+S COMPAREF4
+S COMPAREF8
# Boolean comparisons
S IFEQ