hop_add_insel(hop, "lwz r0, %d(fp)", current_proc->spills_size + 4);
hop_add_insel(hop, "addi sp, fp, %d", current_proc->fp_to_ab);
hop_add_insel(hop, "mr fp, r0");
- hop_add_insel(hop, "blr");
+ hop_add_insel(hop, "bclr 20, 0, 0");
return hop;
}
/* Locals */
out:(int)reg = in:LOCAL4
- emit "addi %out, fp, #$in"
+ emit "addi %out, fp, $in"
cost 4;
address = in:LOCAL4
cost 4;
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
- emit "bc IFTRUE, EQ, $true"
+ emit "bc 12, 2, $true" /* IFTRUE EQ */
emit "b $false"
cost 8;
CJUMPLE(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
- emit "bc IFTRUE, LE, $true"
+ emit "bc 4, 1, $true" /* IFFALSE GT */
emit "b $false"
cost 8;
CJUMPLT(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
- emit "bc IFTRUE, LT, $true"
+ emit "bc 12, 0, $true" /* IFTRUE LT */
emit "b $false"
cost 8;
CALL(dest:(int)reg)
with corrupted(volatile)
emit "mtspr ctr, %dest"
- emit "bcctrl ALWAYS, 0, 0"
+ emit "bcctrl 20, 0, 0"
cost 8;
JUMP(dest:LABEL4)
/* Conversions */
out:(int)reg = CIU44(in:(int)reg)
- emit "mr %out, %in ! ciu44"
+ with %out == %in
+ emit "! ciu44"
cost 4;
out:(int)reg = CUI44(in:(int)reg)
- emit "mr %out, %in ! cui44"
+ with %out == %in
+ emit "! cui44"
cost 4;
cost 4;
out:(int)reg = SUB4(left:(int)reg, right:CONST4)
- emit "addi %out, %left, -($right)"
+ emit "addi %out, %left, -[$right]"
cost 4;
out:(int)reg = MUL4(left:(int)reg, right:(int)reg)
emit "neg %out, %left"
cost 4;
+ out:(int)reg = AND4(left:CONST4, right:(int)reg)
+ emit "andi. %out, %right, $left"
+ cost 4;
+
+ out:(int)reg = AND4(left:(int)reg, right:CONST4)
+ emit "andi. %out, %left, $right"
+ cost 4;
+
+ out:(int)reg = AND4(left:(int)reg, right:(int)reg)
+ emit "and %out, %left, %right"
+ cost 4;
+
out:(int)reg = OR4(left:(int)reg, right:(int)reg)
emit "or %out, %right, %left"
cost 4;
);
break;
+ case op_loe:
+ push(
+ new_ir1(
+ IR_LOAD, EM_wordsize,
+ new_ir2(
+ IR_ADD, EM_pointersize,
+ new_labelir(".hol0"),
+ new_wordir(value)
+ )
+ )
+ );
+ break;
+
+ case op_ste:
+ appendir(
+ new_ir2(
+ IR_STORE, EM_wordsize,
+ new_ir2(
+ IR_ADD, EM_pointersize,
+ new_labelir(".hol0"),
+ new_wordir(value)
+ ),
+ pop(EM_wordsize)
+ )
+ );
+ break;
+
+ case op_zre:
+ appendir(
+ new_ir2(
+ IR_STORE, EM_wordsize,
+ new_ir2(
+ IR_ADD, EM_pointersize,
+ new_labelir(".hol0"),
+ new_wordir(value)
+ ),
+ new_wordir(0)
+ )
+ );
+ break;
+
case op_loc:
push(
new_wordir(value)
case op_stf:
{
struct ir* ptr = pop(EM_pointersize);
- struct ir* val = pop(value);
+ struct ir* val = pop(EM_wordsize);
appendir(
new_ir2(
break;
}
+ case op_fef:
+ {
+ struct ir* e;
+ struct ir* f = pop(value);
+ /* fef is implemented by synthesising a call to frexp. */
+ push(
+ new_labelir(".fef_exp")
+ );
+ push(
+ f
+ );
+ materialise_stack();
+ appendir(
+ new_ir1(
+ IR_CALL, 0,
+ new_labelir((value == 4) ? "frexpf" : "frexp")
+ )
+ );
+ 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
+ );
+
+ break;
+ }
+
case op_lin:
{
/* Set line number --- ignore. */
);
break;
+ case op_ine:
+ appendir(
+ new_ir2(
+ IR_STORE, EM_wordsize,
+ address_of_external(label, offset),
+ new_ir2(
+ IR_ADD, EM_wordsize,
+ new_ir1(
+ IR_LOAD, EM_wordsize,
+ address_of_external(label, offset)
+ ),
+ new_wordir(1)
+ )
+ )
+ );
+ break;
+
+ case op_dee:
+ appendir(
+ new_ir2(
+ IR_STORE, EM_wordsize,
+ address_of_external(label, offset),
+ new_ir2(
+ IR_ADD, EM_wordsize,
+ new_ir1(
+ IR_LOAD, EM_wordsize,
+ address_of_external(label, offset)
+ ),
+ new_wordir(-1)
+ )
+ )
+ );
+ break;
+
case op_cal:
assert(offset == 0);
materialise_stack();